--- loncom/interface/domainprefs.pm 2019/07/30 11:14:53 1.160.6.93 +++ loncom/interface/domainprefs.pm 2017/11/30 02:17:50 1.319 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.160.6.93 2019/07/30 11:14:53 raeburn Exp $ +# $Id: domainprefs.pm,v 1.319 2017/11/30 02:17:50 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -27,7 +27,7 @@ # # ############################################################### -############################################################## +############################################################### =pod @@ -104,8 +104,8 @@ $datatable - HTML containing form eleme 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, and textbook). In each case the radio buttons -allow the selection of one of four values: +(official, unofficial, community, textbook, and placement). +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: @@ -170,10 +170,12 @@ 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; @@ -216,13 +218,27 @@ sub handler { 'contacts','defaults','scantron','coursecategories', 'serverstatuses','requestcourses','helpsettings', 'coursedefaults','usersessions','loadbalancing', - 'requestauthor','selfenrollment','inststatus'],$dom); + 'requestauthor','selfenrollment','inststatus', + 'ltitools','ssl','trust'],$dom); + if (ref($domconfig{'ltitools'}) eq 'HASH') { + my %encconfig = + &Apache::lonnet::get_dom('encconfig',['ltitools'],$dom); + if (ref($encconfig{'ltitools'}) eq 'HASH') { + foreach my $id (keys(%{$domconfig{'ltitools'}})) { + if (ref($domconfig{'ltitools'}{$id}) eq 'HASH') { + foreach my $item ('key','secret') { + $domconfig{'ltitools'}{$id}{$item} = $encconfig{'ltitools'}{$id}{$item}; + } + } + } + } + } my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll', 'autoupdate','autocreate','directorysrch','contacts', 'usercreation','selfcreation','usermodification','scantron', 'requestcourses','requestauthor','coursecategories', 'serverstatuses','helpsettings','coursedefaults', - 'selfenrollment','usersessions'); + 'ltitools','selfenrollment','usersessions','ssl','trust'); my %existing; if (ref($domconfig{'loadbalancing'}) eq 'HASH') { %existing = %{$domconfig{'loadbalancing'}}; @@ -452,6 +468,14 @@ sub handler { 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', @@ -475,6 +499,52 @@ sub handler { 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, + }, ); if (keys(%servers) > 1) { $prefs{'login'} = { text => 'Log-in page options', @@ -654,6 +724,12 @@ sub process_changes { $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); } return $output; } @@ -680,13 +756,13 @@ sub print_config_box { &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, + &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, \@templateroles); } $output .= '<table class="LC_nested_outer"> <tr> - <th align="left" valign="middle"><span class="LC_nobreak">'. + <th class="LC_left_item LC_middle"><span class="LC_nobreak">'. &mt($item->{text}).' '. &Apache::loncommon::help_open_topic($item->{'help'}).'</span></th>'."\n". '</tr>'; @@ -717,8 +793,9 @@ sub print_config_box { $rowtotal ++; if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') || ($action eq 'usermodification') || ($action eq 'defaults') || ($action eq 'coursedefaults') || - ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'directorysrch') || - ($action eq 'helpsettings') || ($action eq 'contacts')) { + ($action eq 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'ssl') || + ($action eq 'directorysrch') || ($action eq 'trust') || ($action eq 'helpsettings') || + ($action eq 'contacts')) { $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal); } elsif ($action eq 'coursecategories') { $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal); @@ -748,15 +825,46 @@ sub print_config_box { $rowtotal ++; if (($action eq 'autoupdate') || ($action eq 'usercreation') || ($action eq 'selfcreation') || ($action eq 'selfenrollment') || - ($action eq 'usersessions') || ($action eq 'coursecategories') || - ($action eq 'contacts') || ($action eq 'defaults')) { + ($action eq 'usersessions') || ($action eq 'coursecategories') || + ($action eq 'trust') || ($action eq 'contacts') || ($action eq 'defaults')) { if ($action eq 'coursecategories') { $output .= &print_coursecategories('middle',$dom,$item,$settings,\$rowtotal); $colspan = ' colspan="2"'; + } elsif ($action eq 'trust') { + $output .= $item->{'print'}->('shared',$dom,$settings,\$rowtotal); } else { $output .= $item->{'print'}->('middle',$dom,$settings,\$rowtotal); } - $output .= ' + if ($action eq 'trust') { + $output .= ' + </table> + </td> + </tr>'; + my @trusthdrs = qw(2 3 4 5 6 7); + my @prefixes = qw(enroll othcoau coaurem domroles catalog reqcrs); + for (my $i=0; $i<@trusthdrs; $i++) { + $output .= ' + <tr> + <td> + <table class="LC_nested"> + <tr class="LC_info_row"> + <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col1'}).'</td> + <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[$trusthdrs[$i]]->{'col2'}).'</td></tr>'. + $item->{'print'}->($prefixes[$i],$dom,$settings,\$rowtotal).' + </table> + </td> + </tr>'; + } + $output .= ' + <tr> + <td> + <table class="LC_nested"> + <tr class="LC_info_row"> + <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col1'}).'</td> + <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[8]->{'col2'}).'</td></tr>'. + $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); + } else { + $output .= ' </table> </td> </tr> @@ -767,16 +875,39 @@ sub print_config_box { <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td> <td class="LC_right_item">'.&mt($item->{'header'}->[2]->{'col2'}).'</td> </tr>'."\n"; - if ($action eq 'coursecategories') { - $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal); - } else { - $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); + if ($action eq 'coursecategories') { + $output .= &print_coursecategories('bottom',$dom,$item,$settings,\$rowtotal); + } else { + $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); + } } $rowtotal ++; } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') || ($action eq 'defaults') || ($action eq 'directorysrch') || ($action eq 'helpsettings')) { $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); + } elsif ($action eq 'ssl') { + $output .= $item->{'print'}->('connto',$dom,$settings,\$rowtotal).' + </table> + </td> + </tr> + <tr> + <td> + <table class="LC_nested"> + <tr class="LC_info_row"> + <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col1'}).'</td> + <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[2]->{'col2'}).'</td></tr>'. + $item->{'print'}->('connfrom',$dom,$settings,\$rowtotal).' + </table> + </td> + </tr> + <tr> + <td> + <table class="LC_nested"> + <tr class="LC_info_row"> + <td class="LC_left_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col1'}).'</td> + <td class="LC_right_item"'.$colspan.'>'.&mt($item->{'header'}->[3]->{'col2'}).'</td></tr>'. + $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); } elsif ($action eq 'login') { if ($numheaders == 4) { $output .= &print_login('page',$dom,$confname,$phase,$settings,\$rowtotal).' @@ -847,8 +978,8 @@ sub print_config_box { <td> <table class="LC_nested"> <tr class="LC_info_row"> - <td class="LC_left_item"'.$colspan.' valign="top">'.&mt($item->{'header'}->[4]->{'col1'}).'</td> - <td class="LC_right_item" valign="top">'.&mt($item->{'header'}->[4]->{'col2'}).'</td> + <td class="LC_left_item"'.$colspan.' style="vertical-align: top">'.&mt($item->{'header'}->[4]->{'col1'}).'</td> + <td class="LC_right_item" style="vertical-align: top">'.&mt($item->{'header'}->[4]->{'col2'}).'</td> </tr>'. &print_validation_rows('requestcourses',$dom,$settings,\$rowtotal); } elsif ($action eq 'requestauthor') { @@ -863,9 +994,9 @@ sub print_config_box { <td> <table class="LC_nested"> <tr class="LC_info_row"> - <td class="LC_left_item"'.$colspan.' valign="top">'. + <td class="LC_left_item"'.$colspan.' style="vertical-align: top">'. &mt($item->{'header'}->[2]->{'col1'}).'</td> - <td class="LC_right_item" valign="top">'. + <td class="LC_right_item" style="vertical-align: top">'. &mt($item->{'header'}->[2]->{'col2'}).'</td> </tr>'. &print_rolecolors($phase,'author',$dom,$confname,$settings,\$rowtotal).' @@ -893,30 +1024,30 @@ sub print_config_box { <td class="LC_left_item" colspan="2">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>'; } elsif ($action eq 'serverstatuses') { $output .= ' - <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}). + <td class="LC_left_item" style="vertical-align: top">'.&mt($item->{'header'}->[0]->{'col1'}). '<br />('.&mt('Automatic access for Dom. Coords.').')</td>'; } else { $output .= ' - <td class="LC_left_item" valign="top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>'; + <td class="LC_left_item" style="vertical-align: top">'.&mt($item->{'header'}->[0]->{'col1'}).'</td>'; } if (defined($item->{'header'}->[0]->{'col3'})) { - $output .= '<td class="LC_left_item" valign="top">'. + $output .= '<td class="LC_left_item" style="vertical-align: top">'. &mt($item->{'header'}->[0]->{'col2'}); if ($action eq 'serverstatuses') { $output .= '<br />(<tt>'.&mt('user1:domain1,user2:domain2 etc.').'</tt>)'; } } else { - $output .= '<td class="LC_right_item" valign="top">'. + $output .= '<td class="LC_right_item" style="vertical-align: top">'. &mt($item->{'header'}->[0]->{'col2'}); } $output .= '</td>'; if ($item->{'header'}->[0]->{'col3'}) { if (defined($item->{'header'}->[0]->{'col4'})) { - $output .= '<td class="LC_left_item" valign="top">'. + $output .= '<td class="LC_left_item" style="vertical-align: top">'. &mt($item->{'header'}->[0]->{'col3'}); } else { - $output .= '<td class="LC_right_item" valign="top">'. + $output .= '<td class="LC_right_item" style="vertical-align: top">'. &mt($item->{'header'}->[0]->{'col3'}); } if ($action eq 'serverstatuses') { @@ -925,7 +1056,7 @@ sub print_config_box { $output .= '</td>'; } if ($item->{'header'}->[0]->{'col4'}) { - $output .= '<td class="LC_right_item" valign="top">'. + $output .= '<td class="LC_right_item" style="vertical-align: top">'. &mt($item->{'header'}->[0]->{'col4'}); } $output .= '</tr>'; @@ -933,7 +1064,8 @@ sub print_config_box { if ($action eq 'quotas') { $output .= &print_quotas($dom,$settings,\$rowtotal,$action); } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || - ($action eq 'serverstatuses') || ($action eq 'loadbalancing')) { + ($action eq 'serverstatuses') || ($action eq 'loadbalancing') || + ($action eq 'ltitools')) { $output .= $item->{'print'}->($dom,$settings,\$rowtotal); } elsif ($action eq 'scantron') { $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal); @@ -957,7 +1089,7 @@ sub print_login { my $choice = $choices{'disallowlogin'}; $css_class = ' class="LC_odd_row"'; $datatable .= '<tr'.$css_class.'><td>'.$choice.'</td>'. - '<td align="right"><table><tr><th>'.$choices{'hostid'}.'</th>'. + '<td style="text-align: right"><table><tr><th>'.$choices{'hostid'}.'</th>'. '<th>'.$choices{'server'}.'</th>'. '<th>'.$choices{'serverpath'}.'</th>'. '<th>'.$choices{'custompath'}.'</th>'. @@ -1238,7 +1370,7 @@ sub print_login { my $choice = $choices{'headtag'}; $css_class = ' class="LC_odd_row"'; $datatable .= '<tr'.$css_class.'><td colspan="2">'.$choice.'</td>'. - '<td align="left"><table><tr><th>'.$choices{'hostid'}.'</th>'. + '<td style="text-align: left"><table><tr><th>'.$choices{'hostid'}.'</th>'. '<th>'.$choices{'current'}.'</th>'. '<th>'.$choices{'action'}.'</th>'. '<th>'.$choices{'exempt'}.'</th></tr>'."\n"; @@ -1281,7 +1413,7 @@ sub print_login { } else { $datatable .= '<input type="file" name="loginheadtag_'.$lonhost.'" />'; } - $datatable .= '</td><td><input type="text" name="loginheadtagexempt_'.$lonhost.'" value="'.$exempt.'" /></td></tr>'; + $datatable .= '</td><td><input type="textbox" name="loginheadtagexempt_'.$lonhost.'" value="'.$exempt.'" /></td></tr>'; } $datatable .= '</table></td></tr>'; } @@ -1441,7 +1573,7 @@ sub display_color_options { my $datatable = '<tr'.$css_class.'>'. '<td>'.$choices->{'font'}.'</td>'; if (!$is_custom->{'font'}) { - $datatable .= '<td>'.&mt('Default in use:').' <span class="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>'; + $datatable .= '<td>'.&mt('Default in use:').' <span id="css_default_'.$role.'_font" style="color: '.$defaults->{'font'}.';">'.$defaults->{'font'}.'</span></td>'; } else { $datatable .= '<td> </td>'; } @@ -1450,12 +1582,12 @@ sub display_color_options { $datatable .= '<td><span class="LC_nobreak">'. '<input type="text" class="colorchooser" size="10" name="'.$role.'_font"'. ' value="'.$current_color.'" /> '. - ' </span></td></tr>'; + ' </td></tr>'; unless ($role eq 'login') { $datatable .= '<tr'.$css_class.'>'. '<td>'.$choices->{'fontmenu'}.'</td>'; if (!$is_custom->{'fontmenu'}) { - $datatable .= '<td>'.&mt('Default in use:').' <span class="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>'; + $datatable .= '<td>'.&mt('Default in use:').' <span id="css_default_'.$role.'_font" style="color: '.$defaults->{'fontmenu'}.';">'.$defaults->{'fontmenu'}.'</span></td>'; } else { $datatable .= '<td> </td>'; } @@ -1465,7 +1597,7 @@ sub display_color_options { '<input class="colorchooser" type="text" size="10" name="' .$role.'_fontmenu"'. ' value="'.$current_color.'" /> '. - ' </span></td></tr>'; + ' </td></tr>'; } my $switchserver = &check_switchserver($dom,$confname); foreach my $img (@{$images}) { @@ -1583,7 +1715,7 @@ sub display_color_options { my $bgs_def; foreach my $item (@{$bgs}) { if (!$is_custom->{$item}) { - $bgs_def .= '<td><span class="LC_nobreak">'.$choices->{$item}.'</span> <span class="css_default_'.$role.'_'.$item.'" style="background-color: '.$defaults->{'bgs'}{$item}.';"> </span><br />'.$defaults->{'bgs'}{$item}.'</td>'; + $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>'; } } if ($bgs_def) { @@ -1595,7 +1727,7 @@ sub display_color_options { '<table border="0"><tr>'; foreach my $item (@{$bgs}) { - $datatable .= '<td align="center">'.$choices->{$item}; + $datatable .= '<td style="text-align: center">'.$choices->{$item}; my $color = $designs->{'bgs'}{$item} ? $designs->{'bgs'}{$item} : $defaults->{'bgs'}{$item}; if ($designs->{'bgs'}{$item}) { $datatable .= ' '; @@ -1611,7 +1743,7 @@ sub display_color_options { my $links_def; foreach my $item (@{$links}) { if (!$is_custom->{$item}) { - $links_def .= '<td>'.$choices->{$item}.'<br /><span class="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>'; + $links_def .= '<td>'.$choices->{$item}.'<br /><span id="css_default_'.$role.'_'.$item.'" style="color: '.$defaults->{'links'}{$item}.';">'.$defaults->{'links'}{$item}.'</span></td>'; } } if ($links_def) { @@ -1623,7 +1755,7 @@ sub display_color_options { '<table border="0"><tr>'; foreach my $item (@{$links}) { my $color = $designs->{'links'}{$item} ? $designs->{'links'}{$item} : $defaults->{'links'}{$item}; - $datatable .= '<td align="center">'.$choices->{$item}."\n"; + $datatable .= '<td style="text-align: center">'.$choices->{$item}."\n"; if ($designs->{'links'}{$item}) { $datatable.=' '; } @@ -1684,7 +1816,7 @@ sub login_text_colors { my ($img,$role,$logintext,$phase,$choices,$designs,$defaults) = @_; my $color_menu = '<table border="0"><tr>'; foreach my $item (@{$logintext}) { - $color_menu .= '<td align="center">'.$choices->{$item}; + $color_menu .= '<td style="text-align: center">'.$choices->{$item}; my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item}; $color_menu .= '<br /><input type="text" class="colorchooser" size="8" name="'.$role.'_'.$item.'" value="'.$color. '" onblur = "javascript:colchg_span('."'css_".$role.'_'.$item."'".',this);" /></td>'; @@ -1697,15 +1829,17 @@ sub image_changes { my ($is_custom,$alt_text,$img_import,$showfile,$fullsize,$role,$img,$imgfile,$logincolors) = @_; my $output; if ($img eq 'login') { - $output = '</td><td>'.$logincolors; # suppress image for Log-in header + # suppress image for Log-in header } elsif (!$is_custom) { if ($img ne 'domlogo') { - $output = &mt('Default image:').'<br />'; + $output .= &mt('Default image:').'<br />'; } else { - $output = &mt('Default in use:').'<br />'; + $output .= &mt('Default in use:').'<br />'; } } - if ($img ne 'login') { + if ($img eq 'login') { # suppress image for Log-in header + $output .= '<td>'.$logincolors; + } else { if ($img_import) { $output .= '<input type="hidden" name="'.$role.'_import_'.$img.'" value="'.$imgfile.'" />'; } @@ -1717,7 +1851,7 @@ sub image_changes { $role.'_del_'.$img.'" value="1" />'.&mt('Delete?'). '</label> '.&mt('Replace:').'</span><br />'; } else { - $output .= '<td valign="middle">'.$logincolors.&mt('Upload:').'<br />'; + $output .= '<td class="LC_middle">'.$logincolors.&mt('Upload:').'<br />'; } } return $output; @@ -1736,7 +1870,7 @@ sub print_quotas { my $typecount = 0; my ($css_class,%titles); if ($context eq 'requestcourses') { - @usertools = ('official','unofficial','community','textbook'); + @usertools = ('official','unofficial','community','textbook','placement'); @options =('norequest','approval','validate','autolimit'); %validations = &Apache::lonnet::auto_courserequest_checks($dom); %titles = &courserequest_titles(); @@ -2200,7 +2334,7 @@ sub print_studentcode { my ($settings,$rowtotal) = @_; my $rownum = 0; my ($output,%current); - my @crstypes = ('official','unofficial','community','textbook'); + my @crstypes = ('official','unofficial','community','textbook','placement'); if (ref($settings) eq 'HASH') { if (ref($settings->{'uniquecode'}) eq 'HASH') { foreach my $type (@crstypes) { @@ -2296,8 +2430,7 @@ sub print_textbookcourses { (' 'x2). '<span class="LC_nobreak">'.&mt('Thumbnail:'); if ($image) { - $datatable .= '<span class="LC_nobreak">'. - $imgsrc. + $datatable .= $imgsrc. '<label><input type="checkbox" name="'.$type.'_image_del"'. ' value="'.$key.'" />'.&mt('Delete?').'</label></span> '. '<span class="LC_nobreak"> '.&mt('Replace:').' '; @@ -2328,7 +2461,7 @@ sub print_textbookcourses { $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; } $datatable .= '</select> '."\n". - '<input type="checkbox" name="'.$type.'_addbook" value="1" />'.&mt('Add').'</span></td>'."\n". + '<input type="checkbox" name="'.$type.'_addbook" value="1" />'.&mt('Add').'</td>'."\n". '<td colspan="2">'. '<span class="LC_nobreak">'.&mt('Subject:').'<input type="text" size="15" name="'.$type.'_addbook_subject" value="" /></span> '."\n". (' 'x2). @@ -2345,13 +2478,13 @@ sub print_textbookcourses { } else { $datatable .= '<input type="file" name="'.$type.'_addbook_image" value="" />'; } - $datatable .= '</span>'."\n"; } - $datatable .= '<span class="LC_nobreak">'.&mt('LON-CAPA course:').' '. + $datatable .= '</span>'."\n". + '<span class="LC_nobreak">'.&mt('LON-CAPA course:').' '. &Apache::loncommon::select_dom_form($env{'request.role.domain'},$type.'_addbook_cdom'). '<input type="text" size="25" name="'.$type.'_addbook_cnum" value="" />'. &Apache::loncommon::selectcourse_link - ('display',$type.'_addbook_cnum',$type.'_addbook_cdom',undef,undef,undef,'Course'). + ('display',$type.'_addbook_cnum',$type.'_addbook_cdom',undef,undef,undef,'Course'); '</span></td>'."\n". '</tr>'."\n"; $itemcount ++; @@ -2451,6 +2584,119 @@ $jstext{'templates'}; ENDSCRIPT } +sub ltitools_javascript { + my ($settings) = @_; + my $togglejs = <itools_toggle_js(); + unless (ref($settings) eq 'HASH') { + return $togglejs; + } + my (%ordered,$total,%jstext); + $total = 0; + foreach my $item (keys(%{$settings})) { + if (ref($settings->{$item}) eq 'HASH') { + my $num = $settings->{$item}{'order'}; + $ordered{$num} = $item; + } + } + $total = scalar(keys(%{$settings})); + my @jsarray = (); + foreach my $item (sort {$a <=> $b } (keys(%ordered))) { + push(@jsarray,$ordered{$item}); + } + my $jstext = ' var ltitools = Array('."'".join("','",@jsarray)."'".');'."\n"; + return <<"ENDSCRIPT"; +<script type="text/javascript"> +// <![CDATA[ +function reorderLTITools(form,item) { + var changedVal; +$jstext + var newpos = 'ltitools_add_pos'; + var maxh = 1 + $total; + var current = new Array; + var newitemVal = form.elements[newpos].options[form.elements[newpos].selectedIndex].value; + if (item == newpos) { + changedVal = newitemVal; + } else { + changedVal = form.elements[item].options[form.elements[item].selectedIndex].value; + current[newitemVal] = newpos; + } + for (var i=0; i<ltitools.length; i++) { + var elementName = 'ltitools_'+ltitools[i]; + if (elementName != item) { + if (form.elements[elementName]) { + var currVal = form.elements[elementName].options[form.elements[elementName].selectedIndex].value; + current[currVal] = elementName; + } + } + } + var oldVal; + for (var j=0; j<maxh; j++) { + if (current[j] == undefined) { + oldVal = j; + } + } + if (oldVal < changedVal) { + for (var k=oldVal+1; k<=changedVal ; k++) { + var elementName = current[k]; + form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex - 1; + } + } else { + for (var k=changedVal; k<oldVal; k++) { + var elementName = current[k]; + form.elements[elementName].selectedIndex = form.elements[elementName].selectedIndex + 1; + } + } + return; +} + +// ]]> +</script> + +$togglejs + +ENDSCRIPT +} + +sub ltitools_toggle_js { + return <<"ENDSCRIPT"; +<script type="text/javascript"> +// <![CDATA[ + +function toggleLTITools(form,setting,item) { + var radioname = ''; + var divid = ''; + if ((setting == 'passback') || (setting == 'roster')) { + radioname = 'ltitools_'+setting+'_'+item; + divid = 'ltitools_'+setting+'time_'+item; + var num = form.elements[radioname].length; + if (num) { + var setvis = ''; + for (var i=0; i<num; i++) { + if (form.elements[radioname][i].checked) { + if (form.elements[radioname][i].value == '1') { + if (document.getElementById(divid)) { + document.getElementById(divid).style.display = 'inline-block'; + } + setvis = 1; + } + break; + } + } + } + if (!setvis) { + if (document.getElementById(divid)) { + document.getElementById(divid).style.display = 'none'; + } + } + } + return; +} +// ]]> +</script> + +ENDSCRIPT +} + sub print_autoenroll { my ($dom,$settings,$rowtotal) = @_; my $autorun = &Apache::lonnet::auto_run(undef,$dom), @@ -2530,7 +2776,7 @@ sub print_autoenroll { '<td>'.&mt('Failsafe for no drops when institutional data missing').'</td>'. '<td class="LC_right_item"><span class="LC_nobreak">'. '<input type="text" name="autoenroll_failsafe"'. - ' value="'.$failsafe.'" size="4" /></span></td></tr>'; + ' value="'.$failsafe.'" size="4" /></td></tr>'; $$rowtotal += 4; return $datatable; } @@ -2823,7 +3069,7 @@ sub print_contacts { } } elsif ($position eq 'middle') { @mailings = ('errormail','packagesmail','lonstatusmail','requestsmail', - 'updatesmail','idconflictsmail','hostipmail'); + 'updatesmail','idconflictsmail'); foreach my $type (@mailings) { $otheremails{$type} = ''; } @@ -2900,7 +3146,6 @@ sub print_contacts { $checked{'requestsmail'}{'adminemail'} = ' checked="checked" '; $checked{'updatesmail'}{'adminemail'} = ' checked="checked" '; $checked{'idconflictsmail'}{'adminemail'} = ' checked="checked" '; - $checked{'hostipmail'}{'adminemail'} = ' checked="checked" '; } elsif ($position eq 'bottom') { $checked{'helpdeskmail'}{'supportemail'} = ' checked="checked" '; $checked{'otherdomsmail'}{'supportemail'} = ' checked="checked" '; @@ -2925,7 +3170,54 @@ sub print_contacts { $to{$item}.'" /></td></tr>'; $rownum ++; } - } else { + } elsif ($position eq 'bottom') { + $css_class = $rownum%2?' class="LC_odd_row"':''; + $datatable .= '<tr'.$css_class.'>'. + '<td>'.&mt('Extra helpdesk form fields:').'<br />'. + &mt('(e-mail, subject, and description always shown)'). + '</td><td class="LC_left_item">'; + if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') && + (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) { + $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>'; + foreach my $field (@{$fields}) { + $datatable .= '<tr><td>'.$fieldtitles->{$field}; + if (($field eq 'screenshot') || ($field eq 'cc')) { + $datatable .= ' '.&mt('(logged-in users)'); + } + $datatable .='</td><td>'; + my $clickaction; + if ($field eq 'screenshot') { + $clickaction = ' onclick="screenshotSize(this);"'; + } + if (ref($possoptions->{$field}) eq 'ARRAY') { + foreach my $option (@{$possoptions->{$field}}) { + my $checked; + if ($currfield{$field} eq $option) { + $checked = ' checked="checked"'; + } + $datatable .= '<span class="LC_nobreak"><label>'. + '<input type="radio" name="helpform_'.$field.'" '. + 'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}. + '</label></span>'.(' 'x2); + } + } + if ($field eq 'screenshot') { + my $display; + if ($currfield{$field} eq 'no') { + $display = ' style="display:none"'; + } + $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.' />'. + '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'. + '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />'; + } + $datatable .= '</td></tr>'; + } + $datatable .= '</table>'; + } + $datatable .= '</td></tr>'."\n"; + $rownum ++; + } + unless ($position eq 'top') { foreach my $type (@mailings) { $css_class = $rownum%2?' class="LC_odd_row"':''; $datatable .= '<tr'.$css_class.'>'. @@ -2959,7 +3251,7 @@ sub print_contacts { 'value="'.$bccemails{$type}.'" /></fieldset>'. '<fieldset><legend>'.&mt('Optional added text').'</legend>'. &mt('Text automatically added to e-mail:').' '. - '<input type="text" name="'.$type.'_includestr" value="'.$includestr{$type}.'" /><br />'. + '<input type="text" name="'.$type.'_includestr" value="'.$includestr{$type}.'" /><br >'. '<span class="LC_nobreak">'.&mt('Location:').' '. '<label><input type="radio" name="'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'. (' 'x2). @@ -2985,56 +3277,138 @@ sub print_contacts { \%choices,$rownum); $datatable .= $reports; } elsif ($position eq 'bottom') { - $css_class = $rownum%2?' class="LC_odd_row"':''; - $datatable .= '<tr'.$css_class.'>'. - '<td>'.&mt('Extra helpdesk form fields:').'<br />'. - &mt('(e-mail, subject, and description always shown)'). - '</td><td class="LC_left_item">'; - if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') && - (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) { - $datatable .= '<table><tr><th>'.&mt('Field').'</th><th>'.&mt('Status').'</th></tr>'; - foreach my $field (@{$fields}) { - $datatable .= '<tr><td>'.$fieldtitles->{$field}; - if (($field eq 'screenshot') || ($field eq 'cc')) { - $datatable .= ' '.&mt('(logged-in users)'); - } - $datatable .='</td><td>'; - my $clickaction; - if ($field eq 'screenshot') { - $clickaction = ' onclick="screenshotSize(this);"'; - } - if (ref($possoptions->{$field}) eq 'ARRAY') { - foreach my $option (@{$possoptions->{$field}}) { - my $checked; - if ($currfield{$field} eq $option) { - $checked = ' checked="checked"'; + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + my (@posstypes,%usertypeshash); + if (ref($types) eq 'ARRAY') { + @posstypes = @{$types}; + } + if (@posstypes) { + if (ref($usertypes) eq 'HASH') { + %usertypeshash = %{$usertypes}; + } + my @overridden; + my $numinrow = 4; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'overrides'}) eq 'HASH') { + foreach my $key (sort(keys(%{$settings->{'overrides'}}))) { + if (ref($settings->{'overrides'}{$key}) eq 'HASH') { + push(@overridden,$key); + foreach my $item (@contacts) { + if ($settings->{'overrides'}{$key}{$item}) { + $checked{'override_'.$key}{$item} = ' checked="checked" '; + } + } + $otheremails{'override_'.$key} = $settings->{'overrides'}{$key}{'others'}; + $bccemails{'override_'.$key} = $settings->{'overrides'}{$key}{'bcc'}; + $includeloc{'override_'.$key} = ''; + $includestr{'override_'.$key} = ''; + if ($settings->{'overrides'}{$key}{'include'} ne '') { + ($includeloc{'override_'.$key},$includestr{'override_'.$key}) = + split(/:/,$settings->{'overrides'}{$key}{'include'},2); + $includestr{'override_'.$key} = &unescape($includestr{'override_'.$key}); + } } - $datatable .= '<span class="LC_nobreak"><label>'. - '<input type="radio" name="helpform_'.$field.'" '. - 'value="'.$option.'"'.$checked.$clickaction.' />'.$fieldoptions->{$option}. - '</label></span>'.(' 'x2); } } - if ($field eq 'screenshot') { - my $display; - if ($currfield{$field} eq 'no') { - $display = ' style="display:none"'; - } - $datatable .= '</td></tr><tr id="help_screenshotsize"'.$display.'>'. - '<td>'.&mt('Maximum size for upload (MB)').'</td><td>'. - '<input type="text" size="5" name="helpform_maxsize" value="'.$maxsize.'" />'; + } + my $customclass = 'LC_helpdesk_override'; + my $optionsprefix = 'LC_options_helpdesk_'; + + my $onclicktypes = "toggleHelpdeskRow(this.form,'overrides','$customclass','$optionsprefix');"; + + $datatable .= &insttypes_row($settings,$types,$usertypes,$dom, + $numinrow,$othertitle,'overrides', + \$rownum,$onclicktypes,$customclass); + $rownum ++; + $usertypeshash{'default'} = $othertitle; + foreach my $status (@posstypes) { + my $css_class; + if ($rownum%2) { + $css_class = 'LC_odd_row '; + } + $css_class .= $customclass; + my $rowid = $optionsprefix.$status; + my $hidden = 1; + my $currstyle = 'display:none'; + if (grep(/^\Q$status\E$/,@overridden)) { + $currstyle = 'display:table-row'; + $hidden = 0; + } + my $key = 'override_'.$status; + $datatable .= &overridden_helpdesk($checked{$key},$otheremails{$key},$bccemails{$key}, + $includeloc{$key},$includestr{$key},$status,$rowid, + $usertypeshash{$status},$css_class,$currstyle, + \@contacts,$short_titles); + unless ($hidden) { + $rownum ++; } - $datatable .= '</td></tr>'; } - $datatable .= '</table>'; } - $datatable .= '</td></tr>'."\n"; - $rownum ++; } $$rowtotal += $rownum; return $datatable; } +sub overridden_helpdesk { + my ($checked,$otheremails,$bccemails,$includeloc,$includestr,$type,$rowid, + $typetitle,$css_class,$rowstyle,$contacts,$short_titles) = @_; + my $class = 'LC_left_item'; + if ($css_class) { + $css_class = ' class="'.$css_class.'"'; + } + if ($rowid) { + $rowid = ' id="'.$rowid.'"'; + } + if ($rowstyle) { + $rowstyle = ' style="'.$rowstyle.'"'; + } + my ($output,$description); + $description = &mt('Helpdesk requests from: [_1] in this domain (overrides default)',"<b>$typetitle</b>"); + $output = '<tr'.$css_class.$rowid.$rowstyle.'>'. + "<td>$description</td>\n". + '<td class="'.$class.'" colspan="2">'. + '<fieldset><legend>'.&mt('E-mail recipient(s)').'</legend>'. + '<span class="LC_nobreak">'; + if (ref($contacts) eq 'ARRAY') { + foreach my $item (@{$contacts}) { + my $check; + if (ref($checked) eq 'HASH') { + $check = $checked->{$item}; + } + my $title; + if (ref($short_titles) eq 'HASH') { + $title = $short_titles->{$item}; + } + $output .= '<label>'. + '<input type="checkbox" name="override_'.$type.'"'.$check. + ' value="'.$item.'" />'.$title.'</label> '; + } + } + $output .= '</span><br />'.&mt('Others').': '. + '<input type="text" name="override_'.$type.'_others" '. + 'value="'.$otheremails.'" />'; + my %locchecked; + foreach my $loc ('s','b') { + if ($includeloc eq $loc) { + $locchecked{$loc} = ' checked="checked"'; + last; + } + } + $output .= '<br />'.&mt('Bcc:').(' 'x6). + '<input type="text" name="override_'.$type.'_bcc" '. + 'value="'.$bccemails.'" /></fieldset>'. + '<fieldset><legend>'.&mt('Optional added text').'</legend>'. + &mt('Text automatically added to e-mail:').' '. + '<input type="text" name="override_'.$type.'_includestr" value="'.$includestr.'" /><br >'. + '<span class="LC_nobreak">'.&mt('Location:').' '. + '<label><input type="radio" name="override_'.$type.'_includeloc" value="s"'.$locchecked{'s'}.' />'.&mt('in subject').'</label>'. + (' 'x2). + '<label><input type="radio" name="override_'.$type.'_includeloc" value="b"'.$locchecked{'b'}.' />'.&mt('in body').'</label>'. + '</span></fieldset>'. + '</td></tr>'."\n"; + return $output; +} + sub contacts_javascript { return <<"ENDSCRIPT"; @@ -3052,6 +3426,37 @@ function screenshotSize(field) { return; } +function toggleHelpdeskRow(form,checkbox,target,prefix,docount) { + if (form.elements[checkbox].length != undefined) { + var count = 0; + if (docount) { + for (var i=0; i<form.elements[checkbox].length; i++) { + if (form.elements[checkbox][i].checked) { + count ++; + } + } + } + for (var i=0; i<form.elements[checkbox].length; i++) { + var type = form.elements[checkbox][i].value; + if (document.getElementById(prefix+type)) { + if (form.elements[checkbox][i].checked) { + document.getElementById(prefix+type).style.display = 'table-row'; + if (count % 2 == 1) { + document.getElementById(prefix+type).className = target+' LC_odd_row'; + } else { + document.getElementById(prefix+type).className = target; + } + count ++; + } else { + document.getElementById(prefix+type).style.display = 'none'; + } + } + } + } + return; +} + + // ]]> </script> @@ -3157,7 +3562,7 @@ sub print_helpsettings { my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); $css_class = $itemcount%2?' class="LC_odd_row"':''; my $chgstr = ' onchange="javascript:reorderHelpRoles(this.form,'."'helproles_".$num."_pos'".');"'; - $datatable .= '<tr '.$css_class.'><td valign="top"><b>'.$role.'</b><br />'. + $datatable .= '<tr '.$css_class.'><td style="vertical-align: top"><b>'.$role.'</b><br />'. '<select name="helproles_'.$num.'_pos"'.$chgstr.'>'; for (my $k=0; $k<=$maxnum; $k++) { my $vpos = $k+1; @@ -3196,7 +3601,7 @@ sub print_helpsettings { &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 .= '<tr '.$css_class.'><td valign="top"><span class="LC_nobreak"><label>'. + $datatable .= '<tr '.$css_class.'><td style="vertical-align: top"><span class="LC_nobreak"><label>'. '<input type="hidden" name="helproles_maxnum" value="'.$maxnum.'" />'."\n". '<select name="helproles_'.$count.'_pos"'.$chgstr.'>'; for (my $k=0; $k<$maxnum+1; $k++) { @@ -3226,9 +3631,7 @@ sub print_helpsettings { \@templateroles,$newcust). &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels, \%levelscurrent,$newcust). - '</fieldset>'. - &helpsettings_javascript(\@roles_by_num,$maxnum,$hiddenstr,$formname). - '</td></tr>'; + '</fieldset></td></tr>'; $count ++; $$rowtotal += $count; } @@ -3477,7 +3880,7 @@ sub radiobutton_prefs { foreach my $item (@{$toggles}) { $css_class = $itemcount%2?' class="LC_odd_row"':''; $datatable .= - '<tr'.$css_class.'><td valign="top">'. + '<tr'.$css_class.'><td style="vertical-align: top">'. '<span class="LC_nobreak">'.$choices->{$item}. '</span></td>'; if ($align eq 'left') { @@ -3499,11 +3902,408 @@ sub radiobutton_prefs { return ($datatable,$itemcount); } +sub print_ltitools { + my ($dom,$settings,$rowtotal) = @_; + my $rownum = 0; + my $css_class; + my $itemcount = 1; + my $maxnum = 0; + my %ordered; + if (ref($settings) eq 'HASH') { + foreach my $item (keys(%{$settings})) { + if (ref($settings->{$item}) eq 'HASH') { + my $num = $settings->{$item}{'order'}; + $ordered{$num} = $item; + } + } + } + my $confname = $dom.'-domainconfig'; + my $switchserver = &check_switchserver($dom,$confname); + my $maxnum = scalar(keys(%ordered)); + my $datatable = <itools_javascript($settings); + my %lt = <itools_names(); + my @courseroles = ('cc','in','ta','ep','st'); + my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner); + my @fields = ('fullname','firstname','lastname','email','user','roles'); + if (keys(%ordered)) { + my @items = sort { $a <=> $b } keys(%ordered); + for (my $i=0; $i<@items; $i++) { + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $item = $ordered{$items[$i]}; + my ($title,$key,$secret,$url,$imgsrc); + if (ref($settings->{$item}) eq 'HASH') { + $title = $settings->{$item}->{'title'}; + $url = $settings->{$item}->{'url'}; + $key = $settings->{$item}->{'key'}; + $secret = $settings->{$item}->{'secret'}; + my $image = $settings->{$item}->{'image'}; + if ($image ne '') { + $imgsrc = '<img src="'.$image.'" alt="'.&mt('Tool Provider icon').'" />'; + } + } + my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_".$item."'".');"'; + $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">' + .'<select name="ltitools_'.$item.'"'.$chgstr.'>'; + for (my $k=0; $k<=$maxnum; $k++) { + my $vpos = $k+1; + my $selstr; + if ($k == $i) { + $selstr = ' selected="selected" '; + } + $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; + } + $datatable .= '</select>'.(' 'x2). + '<label><input type="checkbox" name="ltitools_del" value="'.$item.'" />'. + &mt('Delete?').'</label></span></td>'. + '<td colspan="2">'. + '<fieldset><legend>'.&mt('Required settings').'</legend>'. + '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_title_'.$i.'" value="'.$title.'" /></span> '. + (' 'x2). + '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_version_'.$i.'">'. + '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '. + (' 'x2). + '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_msgtype_'.$i.'">'. + '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '. + '<br /><br />'. + '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_url_'.$i.'"'. + ' value="'.$url.'" /></span>'. + (' 'x2). + '<span class="LC_nobreak">'.$lt{'key'}.':'. + '<input type="text" size="25" name="ltitools_key_'.$i.'" value="'.$key.'" /></span> '. + (' 'x2). + '<span class="LC_nobreak">'.$lt{'secret'}.':'. + '<input type="password" size="20" name="ltitools_secret_'.$i.'" value="'.$secret.'" />'. + '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_secret_'.$i.'.type='."'text'".' } else { this.form.ltitools_secret_'.$i.'.type='."'password'".' }" />'.&mt('Visible input').'</label>'. + '<input type="hidden" name="ltitools_id_'.$i.'" value="'.$item.'" /></span>'. + '</fieldset>'. + '<fieldset><legend>'.&mt('Optional settings').'</legend>'. + '<span class="LC_nobreak">'.&mt('Display target:'); + my %currdisp; + if (ref($settings->{$item}->{'display'}) eq 'HASH') { + if ($settings->{$item}->{'display'}->{'target'} eq 'window') { + $currdisp{'window'} = ' checked="checked"'; + } elsif ($settings->{$item}->{'display'}->{'target'} eq 'tab') { + $currdisp{'tab'} = ' checked="checked"'; + } else { + $currdisp{'iframe'} = ' checked="checked"'; + } + if ($settings->{$item}->{'display'}->{'width'} =~ /^(\d+)$/) { + $currdisp{'width'} = $1; + } + if ($settings->{$item}->{'display'}->{'height'} =~ /^(\d+)$/) { + $currdisp{'height'} = $1; + } + $currdisp{'linktext'} = $settings->{$item}->{'display'}->{'linktext'}; + $currdisp{'explanation'} = $settings->{$item}->{'display'}->{'explanation'}; + } else { + $currdisp{'iframe'} = ' checked="checked"'; + } + foreach my $disp ('iframe','tab','window') { + $datatable .= '<label><input type="radio" name="ltitools_target_'.$i.'" value="'.$disp.'"'.$currdisp{$disp}.' />'. + $lt{$disp}.'</label>'.(' 'x2); + } + $datatable .= (' 'x4); + foreach my $dimen ('width','height') { + $datatable .= '<label>'.$lt{$dimen}.' '. + '<input type="text" name="ltitools_'.$dimen.'_'.$i.'" size="5" value="'.$currdisp{$dimen}.'" /></label>'. + (' 'x2); + } + $datatable .= '<br />'. + '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'. + '<input type="text" name="ltitools_linktext_'.$i.'" size="25" value="'.$currdisp{'linktext'}.'" /></label></div>'. + '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'. + '<textarea name="ltitools_explanation_'.$i.'" rows="5" cols="40">'.$currdisp{'explanation'}. + '</textarea></div><div style=""></div><br />'; + my %units = ( + 'passback' => 'days', + 'roster' => 'seconds', + ); + foreach my $extra ('passback','roster') { + my $validsty = 'none'; + my $currvalid; + my $checkedon = ''; + my $checkedoff = ' checked="checked"'; + if ($settings->{$item}->{$extra}) { + $checkedon = $checkedoff; + $checkedoff = ''; + $validsty = 'inline-block'; + if ($settings->{$item}->{$extra.'valid'} =~ /^\d+\.?\d*$/) { + $currvalid = $settings->{$item}->{$extra.'valid'}; + } + } + my $onclick = ' onclick="toggleLTITools(this.form,'."'$extra','$i'".');"'; + $datatable .= '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{$extra}.' '. + '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="0"'.$checkedoff.$onclick.' />'. + &mt('No').'</label>'.(' 'x2). + '<label><input type="radio" name="ltitools_'.$extra.'_'.$i.'" value="1"'.$checkedon.$onclick.' />'. + &mt('Yes').'</label></span></div>'. + '<div class="LC_floatleft" style="display:'.$validsty.';" id="ltitools_'.$extra.'time_'.$i.'">'. + '<span class="LC_nobreak">'. + &mt("at least [_1] $units{$extra} after launch", + '<input type="text" name="ltitools_'.$extra.'valid_'.$i.'" value="'.$currvalid.'" />'). + '</span></div><div style="padding:0;clear:both;margin:0;border:0"></div>'; + } + $datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.': '; + if ($imgsrc) { + $datatable .= $imgsrc. + '<label><input type="checkbox" name="ltitools_image_del"'. + ' value="'.$item.'" />'.&mt('Delete?').'</label></span> '. + '<span class="LC_nobreak"> '.&mt('Replace:').' '; + } else { + $datatable .= '('.&mt('if larger than 21x21 pixels, image will be scaled').') '; + } + if ($switchserver) { + $datatable .= &mt('Upload to library server: [_1]',$switchserver); + } else { + $datatable .= '<input type="file" name="ltitools_image_'.$i.'" value="" />'; + } + $datatable .= '</span></fieldset>'; + my (%checkedfields,%rolemaps); + if (ref($settings->{$item}) eq 'HASH') { + if (ref($settings->{$item}->{'fields'}) eq 'HASH') { + %checkedfields = %{$settings->{$item}->{'fields'}}; + } + if (ref($settings->{$item}->{'roles'}) eq 'HASH') { + %rolemaps = %{$settings->{$item}->{'roles'}}; + $checkedfields{'roles'} = 1; + } + } + $datatable .= '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'. + '<span class="LC_nobreak">'; + foreach my $field (@fields) { + my $checked; + if ($checkedfields{$field}) { + $checked = ' checked="checked"'; + } + $datatable .= '<label>'. + '<input type="checkbox" name="ltitools_fields_'.$i.'" value="'.$field.'"'.$checked.' />'. + $lt{$field}.'</label>'.(' ' x2); + } + $datatable .= '</span></fieldset>'. + '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>'; + foreach my $role (@courseroles) { + my ($selected,$selectnone); + if (!$rolemaps{$role}) { + $selectnone = ' selected="selected"'; + } + $datatable .= '<td style="text-align: center">'. + &Apache::lonnet::plaintext($role,'Course').'<br />'. + '<select name="ltitools_roles_'.$role.'_'.$i.'">'. + '<option value=""'.$selectnone.'>'.&mt('Select').'</option>'; + foreach my $ltirole (@ltiroles) { + unless ($selectnone) { + if ($rolemaps{$role} eq $ltirole) { + $selected = ' selected="selected"'; + } else { + $selected = ''; + } + } + $datatable .= '<option value="'.$ltirole.'"'.$selected.'>'.$ltirole.'</option>'; + } + $datatable .= '</select></td>'; + } + $datatable .= '</tr></table></fieldset>'; + my %courseconfig; + if (ref($settings->{$item}) eq 'HASH') { + if (ref($settings->{$item}->{'crsconf'}) eq 'HASH') { + %courseconfig = %{$settings->{$item}->{'crsconf'}}; + } + } + $datatable .= '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">'; + foreach my $item ('label','title','target','linktext','explanation','append') { + my $checked; + if ($courseconfig{$item}) { + $checked = ' checked="checked"'; + } + $datatable .= '<label>'. + '<input type="checkbox" name="ltitools_courseconfig_'.$i.'" value="'.$item.'"'.$checked.' />'. + $lt{'crs'.$item}.'</label>'.(' ' x2)."\n"; + } + $datatable .= '</span></fieldset>'. + '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'. + '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>'; + if (ref($settings->{$item}->{'custom'}) eq 'HASH') { + my %custom = %{$settings->{$item}->{'custom'}}; + if (keys(%custom) > 0) { + foreach my $key (sort(keys(%custom))) { + $datatable .= '<tr><td><span class="LC_nobreak">'. + '<label><input type="checkbox" name="ltitools_customdel_'.$i.'" value="'. + $key.'" />'.&mt('Delete').'</label></span></td><td>'.$key.'</td>'. + '<td><input type="text" name="ltitools_customval_'.$key.'_'.$i.'"'. + ' value="'.$custom{$key}.'" /></td></tr>'; + } + } + } + $datatable .= '<tr><td><span class="LC_nobreak">'. + '<label><input type="checkbox" name="ltitools_customadd" value="'.$i.'" />'. + &mt('Add').'</label></span></td><td><input type="text" name="ltitools_custom_name_'.$i.'" />'. + '</td><td><input type="text" name="ltitools_custom_value_'.$i.'" /></td></tr>'; + $datatable .= '</table></fieldset></td></tr>'."\n"; + $itemcount ++; + } + } + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $chgstr = ' onchange="javascript:reorderLTITools(this.form,'."'ltitools_add_pos'".');"'; + $datatable .= '<tr '.$css_class.'><td><span class="LC_nobreak">'."\n". + '<input type="hidden" name="ltitools_maxnum" value="'.$maxnum.'" />'."\n". + '<select name="ltitools_add_pos"'.$chgstr.'>'; + for (my $k=0; $k<$maxnum+1; $k++) { + my $vpos = $k+1; + my $selstr; + if ($k == $maxnum) { + $selstr = ' selected="selected" '; + } + $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; + } + $datatable .= '</select> '."\n". + '<input type="checkbox" name="ltitools_add" value="1" />'.&mt('Add').'</td>'."\n". + '<td colspan="2">'. + '<fieldset><legend>'.&mt('Required settings').'</legend>'. + '<span class="LC_nobreak">'.$lt{'title'}.':<input type="text" size="30" name="ltitools_add_title" value="" /></span> '."\n". + (' 'x2). + '<span class="LC_nobreak">'.$lt{'version'}.':<select name="ltitools_add_version">'. + '<option value="LTI-1p0" selected="selected">1.1</option></select></span> '."\n". + (' 'x2). + '<span class="LC_nobreak">'.$lt{'msgtype'}.':<select name="ltitools_add_msgtype">'. + '<option value="basic-lti-launch-request" selected="selected">Launch</option></select></span> '. + '<br />'. + '<span class="LC_nobreak">'.$lt{'url'}.':<input type="text" size="30" name="ltitools_add_url" value="" /></span> '."\n". + (' 'x2). + '<span class="LC_nobreak">'.$lt{'key'}.':<input type="text" size="25" name="ltitools_add_key" value="" /></span> '."\n". + (' 'x2). + '<span class="LC_nobreak">'.$lt{'secret'}.':<input type="password" size="20" name="ltitools_add_secret" value="" />'. + '<label><input type="checkbox" name="visible" onclick="if (this.checked) { this.form.ltitools_add_secret.type='."'text'".' } else { this.form.ltitools_add_secret.type='."'password'".' }" />'.&mt('Visible input').'</label></span> '."\n". + '</fieldset>'. + '<fieldset><legend>'.&mt('Optional settings').'</legend>'. + '<span class="LC_nobreak">'.&mt('Display target:'); + my %defaultdisp; + $defaultdisp{'iframe'} = ' checked="checked"'; + foreach my $disp ('iframe','tab','window') { + $datatable .= '<label><input type="radio" name="ltitools_add_target" value="'.$disp.'"'.$defaultdisp{$disp}.' />'. + $lt{$disp}.'</label>'.(' 'x2); + } + $datatable .= (' 'x4); + foreach my $dimen ('width','height') { + $datatable .= '<label>'.$lt{$dimen}.' '. + '<input type="text" name="ltitools_add_'.$dimen.'" size="5" /></label>'. + (' 'x2); + } + $datatable .= '<br />'. + '<div class="LC_left_float">'.$lt{'linktext'}.'<br />'. + '<input type="text" name="ltitools_add_linktext" size="5" /></label></div>'. + '<div class="LC_left_float">'.$lt{'explanation'}.'<br />'. + '<textarea name=ltitools_add_explanation" rows="5" cols="40"></textarea>'. + '</div><div style=""></div><br />'; + my %units = ( + 'passback' => 'days', + 'roster' => 'seconds', + ); + my %defaulttimes = ( + 'passback' => '7', + 'roster' => '300', + ); + foreach my $extra ('passback','roster') { + my $onclick = ' onclick="toggleLTITools(this.form,'."'$extra','add'".');"'; + $datatable .= '<div class="LC_floatleft"><span class="LC_nobreak">'.$lt{$extra}.' '. + '<label><input type="radio" name="ltitools_'.$extra.'_add" value="0" checked="checked"'.$onclick.' />'. + &mt('No').'</label></span>'.(' 'x2).'<span class="LC_nobreak">'. + '<label><input type="radio" name="ltitools_'.$extra.'_add" value="1"'.$onclick.' />'. + &mt('Yes').'</label></span></div>'. + '<div class="LC_floatleft" style="display:none;" id="ltitools_'.$extra.'time_add">'. + '<span class="LC_nobreak">'. + &mt("at least [_1] $units{$extra} after launch", + '<input type="text" name="ltitools_'.$extra.'valid_add" value="'.$defaulttimes{$extra}.'" />'). + '</span></div><div style="padding:0;clear:both;margin:0;border:0"></div>'; + } + $datatable .= '<span class="LC_nobreak">'.$lt{'icon'}.': '. + '('.&mt('if larger than 21x21 pixels, image will be scaled').') '; + if ($switchserver) { + $datatable .= &mt('Upload to library server: [_1]',$switchserver); + } else { + $datatable .= '<input type="file" name="ltitools_add_image" value="" />'; + } + $datatable .= '</span></fieldset>'. + '<fieldset><legend>'.&mt('User data sent on launch').'</legend>'. + '<span class="LC_nobreak">'; + foreach my $field (@fields) { + $datatable .= '<label>'. + '<input type="checkbox" name="ltitools_add_fields" value="'.$field.'" />'. + $lt{$field}.'</label>'.(' ' x2); + } + $datatable .= '</span></fieldset>'. + '<fieldset><legend>'.&mt('Role mapping').'</legend><table><tr>'; + foreach my $role (@courseroles) { + my ($checked,$checkednone); + $datatable .= '<td style="text-align: center">'. + &Apache::lonnet::plaintext($role,'Course').'<br />'. + '<select name="ltitools_add_roles_'.$role.'">'. + '<option value="" selected="selected">'.&mt('Select').'</option>'; + foreach my $ltirole (@ltiroles) { + $datatable .= '<option value="'.$ltirole.'">'.$ltirole.'</option>'; + } + $datatable .= '</select></td>'; + } + $datatable .= '</tr></table></fieldset>'. + '<fieldset><legend>'.&mt('Configurable in course').'</legend><span class="LC_nobreak">'; + foreach my $item ('label','title','target','linktext','explanation','append') { + $datatable .= '<label>'. + '<input type="checkbox" name="ltitools_courseconfig" value="'.$item.'" checked="checked" />'. + $lt{'crs'.$item}.'</label>'.(' ' x2)."\n"; + } + $datatable .= '</span></fieldset>'. + '<fieldset><legend>'.&mt('Custom items sent on launch').'</legend>'. + '<table><tr><th>'.&mt('Action').'</th><th>'.&mt('Name').'</th><th>'.&mt('Value').'</th></tr>'. + '<tr><td><span class="LC_nobreak">'. + '<label><input type="checkbox" name="ltitools_add_custom" value="1" />'. + &mt('Add').'</label></span></td><td><input type="text" name="ltitools_add_custom_name" />'. + '</td><td><input type="text" name="ltitools_add_custom_value" /></td></tr>'. + '</table></fieldset></td></tr>'."\n". + '</td>'."\n". + '</tr>'."\n"; + $itemcount ++; + return $datatable; +} + +sub ltitools_names { + my %lt = &Apache::lonlocal::texthash( + 'title' => 'Title', + 'version' => 'Version', + 'msgtype' => 'Message Type', + 'url' => 'URL', + 'key' => 'Key', + 'secret' => 'Secret', + 'icon' => 'Icon', + 'user' => 'Username:domain', + 'fullname' => 'Full Name', + 'firstname' => 'First Name', + 'lastname' => 'Last Name', + 'email' => 'E-mail', + 'roles' => 'Role', + 'window' => 'Window', + 'tab' => 'Tab', + 'iframe' => 'iFrame', + 'height' => 'Height', + 'width' => 'Width', + 'linktext' => 'Default Link Text', + 'explanation' => 'Default Explanation', + 'passback' => 'Tool can return grades:', + 'roster' => 'Tool can retrieve roster:', + 'crstarget' => 'Display target', + 'crslabel' => 'Course label', + 'crstitle' => 'Course title', + 'crslinktext' => 'Link Text', + 'crsexplanation' => 'Explanation', + 'crsappend' => 'Provider URL', + ); + return %lt; +} + sub print_coursedefaults { my ($position,$dom,$settings,$rowtotal) = @_; my ($css_class,$datatable,%checkedon,%checkedoff,%defaultchecked,@toggles); my $itemcount = 1; my %choices = &Apache::lonlocal::texthash ( + canuse_pdfforms => 'Course/Community users can create/upload PDF forms', uploadquota => 'Default quota for files uploaded directly to course/community using Course Editor (MB)', anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys', coursecredits => 'Credits can be specified for courses', @@ -3515,6 +4315,7 @@ sub print_coursedefaults { mysqltables => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver', ); my %staticdefaults = ( + texengine => 'MathJax', anonsurvey_threshold => 10, uploadquota => 500, postsubmit => 60, @@ -3522,12 +4323,13 @@ sub print_coursedefaults { ); if ($position eq 'top') { %defaultchecked = ( + 'canuse_pdfforms' => 'off', 'uselcmath' => 'on', 'usejsme' => 'on', 'canclone' => 'none', ); - @toggles = ('uselcmath','usejsme'); - my $deftex = $Apache::lonnet::deftex; + @toggles = ('canuse_pdfforms','uselcmath','usejsme'); + my $deftex = $staticdefaults{'texengine'}; if (ref($settings) eq 'HASH') { if ($settings->{'texengine'}) { if ($settings->{'texengine'} =~ /^(MathJax|mimetex|tth)$/) { @@ -3559,7 +4361,7 @@ sub print_coursedefaults { $datatable = $mathdisp.$datatable; $css_class = $itemcount%2?' class="LC_odd_row"':''; $datatable .= - '<tr'.$css_class.'><td valign="top">'. + '<tr'.$css_class.'><td style="vertical-align: top">'. '<span class="LC_nobreak">'.$choices{'canclone'}. '</span></td><td class="LC_left_item">'; my $currcanclone = 'none'; @@ -3603,7 +4405,7 @@ sub print_coursedefaults { if ($checked) { $show = 'block'; } - $additional = '<div id="cloneinstcode" style="display:'.$show.'" />'. + $additional = '<div id="cloneinstcode" style="display:'.$show.';" />'. &mt('Institutional codes for new and cloned course have identical:'). '<br />'; foreach my $item (@code_order) { @@ -3633,7 +4435,7 @@ sub print_coursedefaults { my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql); my $currusecredits = 0; my $postsubmitclient = 1; - my @types = ('official','unofficial','community','textbook'); + my @types = ('official','unofficial','community','textbook','placement'); if (ref($settings) eq 'HASH') { $currdefresponder = $settings->{'anonsurvey_threshold'}; if (ref($settings->{'uploadquota'}) eq 'HASH') { @@ -3711,10 +4513,10 @@ sub print_coursedefaults { $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'. $choices{'uploadquota'}. '</span></td>'. - '<td align="right" class="LC_right_item">'. + '<td style="text-align: right" class="LC_right_item">'. '<table><tr>'; foreach my $type (@types) { - $datatable .= '<td align="center">'.&mt($type).'<br />'. + $datatable .= '<td style="text-align: center">'.&mt($type).'<br />'. '<input type="text" name="uploadquota_'.$type.'"'. ' value="'.$curruploadquota{$type}.'" size="5" /></td>'; } @@ -3729,7 +4531,7 @@ sub print_coursedefaults { '<i>'.&mt('Default credits').'</i><br /><table><tr>'; foreach my $type (@types) { next if ($type eq 'community'); - $additional .= '<td align="center">'.&mt($type).'<br />'. + $additional .= '<td style="text-align: center">'.&mt($type).'<br />'. '<input type="text" name="'.$type.'_credits"'. ' value="'.$defcredits{$type}.'" size="3" /></td>'; } @@ -3753,7 +4555,7 @@ sub print_coursedefaults { '<i>'.&mt('Enter 0 to remain disabled until page reload.').'</i><br />'. '<table><tr>'; foreach my $type (@types) { - $additional .= '<td align="center">'.&mt($type).'<br />'. + $additional .= '<td style="text-align: center">'.&mt($type).'<br />'. '<input type="text" name="'.$type.'_timeout" value="'. $deftimeout{$type}.'" size="5" /></td>'; } @@ -3771,10 +4573,10 @@ sub print_coursedefaults { $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'. $choices{'mysqltables'}. '</span></td>'. - '<td align="right" class="LC_right_item">'. + '<td style="text-align: right" class="LC_right_item">'. '<table><tr>'; foreach my $type (@types) { - $datatable .= '<td align="center">'.&mt($type).'<br />'. + $datatable .= '<td style="text-align: center">'.&mt($type).'<br />'. '<input type="text" name="mysqltables_'.$type.'"'. ' value="'.$currmysql{$type}.'" size="8" /></td>'; } @@ -3790,7 +4592,7 @@ sub print_selfenrollment { my ($position,$dom,$settings,$rowtotal) = @_; my ($css_class,$datatable); my $itemcount = 1; - my @types = ('official','unofficial','community','textbook'); + my @types = ('official','unofficial','community','textbook','placement'); if (($position eq 'top') || ($position eq 'middle')) { my ($rowsref,$titlesref) = &Apache::lonuserutils::get_selfenroll_titles(); my %descs = &Apache::lonuserutils::selfenroll_default_descs(); @@ -3974,7 +4776,7 @@ sub print_validation_rows { '</label></span> '; } } elsif ($item eq 'markup') { - $datatable .= '<textarea name="'.$caller.'_validation_markup" cols="50" rows="5">'. + $datatable .= '<textarea name="'.$caller.'_validation_markup" cols="50" rows="5" wrap="soft">'. $currvalidation{$item}. '</textarea>'; } @@ -3996,7 +4798,7 @@ sub print_validation_rows { my ($numdc,$dctable,$rows) = &active_dc_picker($dom,$numinrow,'radio', 'validationdc',%currhash); my $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; - $datatable .= '<tr'.$css_class.'><td>'; + $datatable .= '</td></tr><tr'.$css_class.'><td>'; if ($numdc > 1) { $datatable .= &mt('Course creation processed as: (choose Dom. Coord.)'); } else { @@ -4013,15 +4815,14 @@ sub print_validation_rows { sub print_usersessions { my ($position,$dom,$settings,$rowtotal) = @_; - my ($css_class,$datatable,%checked,%choices); - my (%by_ip,%by_location,@intdoms); - &build_location_hashes(\@intdoms,\%by_ip,\%by_location); + my ($css_class,$datatable,$itemcount,%checked,%choices); + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); my @alldoms = &Apache::lonnet::all_domains(); my %serverhomes = %Apache::lonnet::serverhomeIDs; my %servers = &Apache::lonnet::internet_dom_servers($dom); my %altids = &id_for_thisdom(%servers); - my $itemcount = 1; if ($position eq 'top') { if (keys(%serverhomes) > 1) { my %spareid = ¤t_offloads_to($dom,$settings,\%servers); @@ -4034,118 +4835,256 @@ sub print_usersessions { $datatable .= &spares_row($dom,\%servers,\%spareid,\%serverhomes,\%altids,$curroffloadnow,$rowtotal); } else { $datatable .= '<tr'.$css_class.'><td colspan="2">'. - &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.'); + &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.'). + '</td></tr>'; } } else { - if (keys(%by_location) == 0) { - $datatable .= '<tr'.$css_class.'><td colspan="2">'. - &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.'); + my %titles = &usersession_titles(); + my ($prefix,@types); + if ($position eq 'bottom') { + $prefix = 'remote'; + @types = ('version','excludedomain','includedomain'); } else { - my %lt = &usersession_titles(); - my $numinrow = 5; - my $prefix; - my @types; - if ($position eq 'bottom') { - $prefix = 'remote'; - @types = ('version','excludedomain','includedomain'); - } else { - $prefix = 'hosted'; - @types = ('excludedomain','includedomain'); - } - my (%current,%checkedon,%checkedoff); - my @lcversions = &Apache::lonnet::all_loncaparevs(); - my @locations = sort(keys(%by_location)); - foreach my $type (@types) { - $checkedon{$type} = ''; - $checkedoff{$type} = ' checked="checked"'; - } - if (ref($settings) eq 'HASH') { - if (ref($settings->{$prefix}) eq 'HASH') { - foreach my $key (keys(%{$settings->{$prefix}})) { - $current{$key} = $settings->{$prefix}{$key}; - if ($key eq 'version') { - if ($current{$key} ne '') { - $checkedon{$key} = ' checked="checked"'; - $checkedoff{$key} = ''; - } - } elsif (ref($current{$key}) eq 'ARRAY') { + $prefix = 'hosted'; + @types = ('excludedomain','includedomain'); + } + ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles); + } + $$rowtotal += $itemcount; + return $datatable; +} + +sub rules_by_location { + my ($settings,$prefix,$by_location,$by_ip,$types,$titles) = @_; + my ($datatable,$itemcount,$css_class); + if (keys(%{$by_location}) == 0) { + $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; + $datatable = '<tr'.$css_class.'><td colspan="2">'. + &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.'). + '</td></tr>'; + $itemcount = 1; + } else { + $itemcount = 0; + my $numinrow = 5; + my (%current,%checkedon,%checkedoff); + my @locations = sort(keys(%{$by_location})); + foreach my $type (@{$types}) { + $checkedon{$type} = ''; + $checkedoff{$type} = ' checked="checked"'; + } + if (ref($settings) eq 'HASH') { + if (ref($settings->{$prefix}) eq 'HASH') { + foreach my $key (keys(%{$settings->{$prefix}})) { + $current{$key} = $settings->{$prefix}{$key}; + if ($key eq 'version') { + if ($current{$key} ne '') { $checkedon{$key} = ' checked="checked"'; $checkedoff{$key} = ''; } + } elsif (ref($current{$key}) eq 'ARRAY') { + $checkedon{$key} = ' checked="checked"'; + $checkedoff{$key} = ''; } } } - foreach my $type (@types) { - next if ($type ne 'version' && !@locations); - $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; - $datatable .= '<tr'.$css_class.'> - <td><span class="LC_nobreak">'.$lt{$type}.'</span><br /> - <span class="LC_nobreak"> - <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label> - <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>'; - if ($type eq 'version') { - my $selector = '<select name="'.$prefix.'_version">'; - foreach my $version (@lcversions) { - my $selected = ''; - if ($current{'version'} eq $version) { - $selected = ' selected="selected"'; - } - $selector .= ' <option value="'.$version.'"'. - $selected.'>'.$version.'</option>'; + } + foreach my $type (@{$types}) { + next if ($type ne 'version' && !@locations); + $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; + $datatable .= '<tr'.$css_class.'> + <td><span class="LC_nobreak">'.$titles->{$type}.'</span><br /> + <span class="LC_nobreak"> + <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedoff{$type}.' value="0" />'.&mt('Not in use').'</label> + <label><input type="radio" name="'.$prefix.'_'.$type.'_inuse" '.$checkedon{$type}.' value="1" />'.&mt('In use').'</label></span></td><td>'; + if ($type eq 'version') { + my @lcversions = &Apache::lonnet::all_loncaparevs(); + my $selector = '<select name="'.$prefix.'_version">'; + foreach my $version (@lcversions) { + my $selected = ''; + if ($current{'version'} eq $version) { + $selected = ' selected="selected"'; } - $selector .= '</select> '; - $datatable .= &mt('remote server must be version: [_1] or later',$selector); - } else { - $datatable.= '<div><input type="button" value="'.&mt('check all').'" '. - 'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'. - ' />'.(' 'x2). - '<input type="button" value="'.&mt('uncheck all').'" '. - 'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'. - "\n". - '</div><div><table>'; - my $rem; - for (my $i=0; $i<@locations; $i++) { - my ($showloc,$value,$checkedtype); - if (ref($by_location{$locations[$i]}) eq 'ARRAY') { - my $ip = $by_location{$locations[$i]}->[0]; - if (ref($by_ip{$ip}) eq 'ARRAY') { - $value = join(':',@{$by_ip{$ip}}); - $showloc = join(', ',@{$by_ip{$ip}}); - if (ref($current{$type}) eq 'ARRAY') { - foreach my $loc (@{$by_ip{$ip}}) { - if (grep(/^\Q$loc\E$/,@{$current{$type}})) { - $checkedtype = ' checked="checked"'; - last; - } + $selector .= ' <option value="'.$version.'"'. + $selected.'>'.$version.'</option>'; + } + $selector .= '</select> '; + $datatable .= &mt('remote server must be version: [_1] or later',$selector); + } else { + $datatable.= '<div><input type="button" value="'.&mt('check all').'" '. + 'onclick="javascript:checkAll(document.display.'.$prefix.'_'.$type.')"'. + ' />'.(' 'x2). + '<input type="button" value="'.&mt('uncheck all').'" '. + 'onclick="javascript:uncheckAll(document.display.'.$prefix.'_'.$type.')" />'. + "\n". + '</div><div><table>'; + my $rem; + for (my $i=0; $i<@locations; $i++) { + my ($showloc,$value,$checkedtype); + if (ref($by_location->{$locations[$i]}) eq 'ARRAY') { + my $ip = $by_location->{$locations[$i]}->[0]; + if (ref($by_ip->{$ip}) eq 'ARRAY') { + $value = join(':',@{$by_ip->{$ip}}); + $showloc = join(', ',@{$by_ip->{$ip}}); + if (ref($current{$type}) eq 'ARRAY') { + foreach my $loc (@{$by_ip->{$ip}}) { + if (grep(/^\Q$loc\E$/,@{$current{$type}})) { + $checkedtype = ' checked="checked"'; + last; } } } } - $rem = $i%($numinrow); - if ($rem == 0) { - if ($i > 0) { - $datatable .= '</tr>'; - } - $datatable .= '<tr>'; - } - $datatable .= '<td class="LC_left_item">'. - '<span class="LC_nobreak"><label>'. - '<input type="checkbox" name="'.$prefix.'_'.$type. - '" value="'.$value.'"'.$checkedtype.' />'.$showloc. - '</label></span></td>'; } - $rem = @locations%($numinrow); - my $colsleft = $numinrow - $rem; - if ($colsleft > 1 ) { - $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'. - ' </td>'; - } elsif ($colsleft == 1) { - $datatable .= '<td class="LC_left_item"> </td>'; + $rem = $i%($numinrow); + if ($rem == 0) { + if ($i > 0) { + $datatable .= '</tr>'; + } + $datatable .= '<tr>'; + } + $datatable .= '<td class="LC_left_item">'. + '<span class="LC_nobreak"><label>'. + '<input type="checkbox" name="'.$prefix.'_'.$type. + '" value="'.$value.'"'.$checkedtype.' />'.$showloc. + '</label></span></td>'; + } + $rem = @locations%($numinrow); + my $colsleft = $numinrow - $rem; + if ($colsleft > 1 ) { + $datatable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'. + ' </td>'; + } elsif ($colsleft == 1) { + $datatable .= '<td class="LC_left_item"> </td>'; + } + $datatable .= '</tr></table>'; + } + $datatable .= '</td></tr>'; + $itemcount ++; + } + } + return ($datatable,$itemcount); +} + +sub print_ssl { + my ($position,$dom,$settings,$rowtotal) = @_; + my ($css_class,$datatable); + my $itemcount = 1; + if ($position eq 'top') { + my $primary_id = &Apache::lonnet::domain($dom,'primary'); + my $intdom = &Apache::lonnet::internet_dom($primary_id); + my $same_institution; + if ($intdom ne '') { + my $internet_names = &Apache::lonnet::get_internet_names($Apache::lonnet::perlvar{'lonHostID'}); + if (ref($internet_names) eq 'ARRAY') { + if (grep(/^\Q$intdom\E$/,@{$internet_names})) { + $same_institution = 1; + } + } + } + $css_class = $itemcount%2?' class="LC_odd_row"':''; + $datatable = '<tr'.$css_class.'><td colspan="2">'; + if ($same_institution) { + my %domservers = &Apache::lonnet::get_servers($dom); + $datatable .= &LONCAPA::SSL::print_certstatus(\%domservers,'web','domprefs'); + } else { + $datatable .= &mt("You need to be logged into one of your own domain's servers to display information about the status of LON-CAPA SSL certificates."); + } + $datatable .= '</td></tr>'; + $itemcount ++; + } else { + my %titles = &ssl_titles(); + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); + my @alldoms = &Apache::lonnet::all_domains(); + my %serverhomes = %Apache::lonnet::serverhomeIDs; + my @domservers = &Apache::lonnet::get_servers($dom); + my %servers = &Apache::lonnet::internet_dom_servers($dom); + my %altids = &id_for_thisdom(%servers); + if (($position eq 'connto') || ($position eq 'connfrom')) { + my $legacy; + unless (ref($settings) eq 'HASH') { + my $name; + if ($position eq 'connto') { + $name = 'loncAllowInsecure'; + } else { + $name = 'londAllowInsecure'; + } + my $primarylibserv = &Apache::lonnet::domain($dom,'primary'); + my @ids=&Apache::lonnet::current_machine_ids(); + if (($primarylibserv ne '') && (!grep(/^\Q$primarylibserv\E$/,@ids))) { + my %what = ( + $name => 1, + ); + my ($result,$returnhash) = + &Apache::lonnet::get_remote_globals($primarylibserv,\%what); + if ($result eq 'ok') { + if (ref($returnhash) eq 'HASH') { + $legacy = $returnhash->{$name}; + } + } + } else { + $legacy = $Apache::lonnet::perlvar{$name}; + } + } + foreach my $type ('dom','intdom','other') { + my %checked; + $css_class = $itemcount%2?' class="LC_odd_row"':''; + $datatable .= '<tr'.$css_class.'><td>'.$titles{$type}.'</td>'. + '<td class="LC_right_item">'; + my $skip; + if ($type eq 'dom') { + unless (keys(%servers) > 1) { + $datatable .= &mt('Nothing to set here, as there are no other servers/VMs'); + $skip = 1; + } + } + if ($type eq 'intdom') { + unless (@instdoms > 1) { + $datatable .= &mt('Nothing to set here, as there are no other domains for this institution'); + $skip = 1; + } + } elsif ($type eq 'other') { + if (keys(%by_location) == 0) { + $datatable .= &mt('Nothing to set here, as there are no other institutions'); + $skip = 1; + } + } + unless ($skip) { + $checked{'yes'} = ' checked="checked"'; + if (ref($settings) eq 'HASH') { + if (ref($settings->{$position}) eq 'HASH') { + if ($settings->{$position}->{$type} =~ /^(no|req)$/) { + $checked{$1} = $checked{'yes'}; + delete($checked{'yes'}); + } + } + } else { + if ($legacy == 0) { + $checked{'req'} = $checked{'yes'}; + delete($checked{'yes'}); + } + } + foreach my $option ('no','yes','req') { + $datatable .= '<span class="LC_nobreak"><label>'. + '<input type="radio" name="'.$position.'_'.$type.'" '. + 'value="'.$option.'"'.$checked{$option}.' />'.$titles{$option}. + '</label></span>'.(' 'x2); } - $datatable .= '</tr></table>'; } $datatable .= '</td></tr>'; + $itemcount ++; + } + } else { + my $prefix = 'replication'; + my @types = ('certreq','nocertreq'); + if (keys(%by_location) == 0) { + $datatable .= '<tr'.$css_class.'><td>'. + &mt('Nothing to set here, as there are no other institutions'). + '</td></tr>'; $itemcount ++; + } else { + ($datatable,$itemcount) = + &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles); } } } @@ -4153,10 +5092,60 @@ sub print_usersessions { return $datatable; } +sub ssl_titles { + return &Apache::lonlocal::texthash ( + dom => 'LON-CAPA servers/VMs from same domain', + intdom => 'LON-CAPA servers/VMs from same "internet" domain', + other => 'External LON-CAPA servers/VMs', + connto => 'Connections to other servers', + connfrom => 'Connections from other servers', + replication => 'Replicating content to other institutions', + certreq => 'Client certificate required, but specific domains exempt', + nocertreq => 'No client certificate required, except for specific domains', + no => 'SSL not used', + yes => 'SSL Optional (used if available)', + req => 'SSL Required', + ); +} + +sub print_trust { + my ($prefix,$dom,$settings,$rowtotal) = @_; + my ($css_class,$datatable,%checked,%choices); + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); + my $itemcount = 1; + my %titles = &trust_titles(); + my @types = ('exc','inc'); + if ($prefix eq 'top') { + $prefix = 'content'; + } elsif ($prefix eq 'bottom') { + $prefix = 'msg'; + } + ($datatable,$itemcount) = &rules_by_location($settings,$prefix,\%by_location,\%by_ip,\@types,\%titles); + $$rowtotal += $itemcount; + return $datatable; +} + +sub trust_titles { + return &Apache::lonlocal::texthash( + content => "Access to this domain's content by others", + shared => "Access to other domain's content by this domain", + enroll => "Enrollment in this domain's courses by others", + othcoau => "Co-author roles in this domain for others", + coaurem => "Co-author roles for this domain's users elsewhere", + domroles => "Domain roles in this domain assignable to others", + catalog => "Course Catalog for this domain displayed elsewhere", + reqcrs => "Requests for creation of courses in this domain by others", + msg => "Users in other domains can send messages to this domain", + exc => "Allow all, but exclude specific domains", + inc => "Deny all, but include specific domains", + ); +} + sub build_location_hashes { - my ($intdoms,$by_ip,$by_location) = @_; + my ($intdoms,$by_ip,$by_location,$instdoms) = @_; return unless((ref($intdoms) eq 'ARRAY') && (ref($by_ip) eq 'HASH') && - (ref($by_location) eq 'HASH')); + (ref($by_location) eq 'HASH') && (ref($instdoms) eq 'ARRAY')); my %iphost = &Apache::lonnet::get_iphost(); my $primary_id = &Apache::lonnet::domain($env{'request.role.domain'},'primary'); my $primary_ip = &Apache::lonnet::get_host_ip($primary_id); @@ -4173,7 +5162,13 @@ sub build_location_hashes { foreach my $id (@{$iphost{$ip}}) { my $location = &Apache::lonnet::internet_dom($id); if ($location) { - next if (grep(/^\Q$location\E$/,@{$intdoms})); + if (grep(/^\Q$location\E$/,@{$intdoms})) { + my $dom = &Apache::lonnet::host_domain($id); + unless (grep(/^\Q$dom\E/,@{$instdoms})) { + push(@{$instdoms},$dom); + } + next; + } if (ref($by_ip->{$ip}) eq 'ARRAY') { unless(grep(/^\Q$location\E$/,@{$by_ip->{$ip}})) { push(@{$by_ip->{$ip}},$location); @@ -4480,7 +5475,7 @@ sub print_loadbalancing { my $disabled_div_style = 'display: block'; my $homedom_div_style = 'display: none'; $datatable .= '<tr class="'.$css_class[$cssidx].'">'. - '<td rowspan="'.$rownum.'" valign="top">'. + '<td rowspan="'.$rownum.'" style="vertical-align: top">'. '<p>'; if ($lonhost eq '') { $datatable .= '<span class="LC_nobreak">'; @@ -4513,7 +5508,7 @@ sub print_loadbalancing { $homedom_div_style = 'display: block'; } } - $datatable .= '</p></td><td rowspan="'.$rownum.'" valign="top">'. + $datatable .= '</p></td><td rowspan="'.$rownum.'" style="vertical-align: top">'. '<div id="loadbalancing_disabled_'.$balnum.'" style="'. $disabled_div_style.'">'.$disabledtext.'</div>'."\n". '<div id="loadbalancing_targets_'.$balnum.'" style="'.$targets_div_style.'">'.&mt('Offloads to:').'<br />'; @@ -4725,10 +5720,10 @@ sub loadbalance_rule_row { } my $space; if ($islast && $num == 1) { - $space = '<div display="inline-block"> </div>'; + $space = '<div style="display:inline-block;"> </div>'; } my $output = - '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td valign="top">'.$space. + '<tr class="'.$css_class.'" id="balanceruletr_'.$balnum.'_'.$num.'"><td style="vertical-align: top">'.$space. '<div id="balanceruletitle_'.$balnum.'_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n". '<td valaign="top">'.$space. '<div id="balancerule_'.$balnum.'_'.$type.'" style="'.$style.'">'."\n"; @@ -4811,13 +5806,12 @@ sub contact_titles { 'adminemail' => 'Default Server Admin E-mail address', 'errormail' => 'Error reports to be e-mailed to', 'packagesmail' => 'Package update alerts to be e-mailed to', - 'helpdeskmail' => "Helpdesk requests for this domain's users", - 'otherdomsmail' => 'Helpdesk requests for other (unconfigured) domains', + 'helpdeskmail' => "Helpdesk requests from all users in this domain", + 'otherdomsmail' => 'Helpdesk requests from users in other (unconfigured) domains', 'lonstatusmail' => 'E-mail from nightly status check (warnings/errors)', 'requestsmail' => 'E-mail from course requests requiring approval', 'updatesmail' => 'E-mail from nightly check of LON-CAPA module integrity/updates', 'idconflictsmail' => 'E-mail from bi-nightly check for multiple users sharing same student/employee ID', - 'hostipmail' => 'E-mail from nightly check of hostname/IP network changes', ); my %short_titles = &Apache::lonlocal::texthash ( adminemail => 'Admin E-mail address', @@ -4864,6 +5858,7 @@ sub tool_titles { unofficial => 'Unofficial courses', community => 'Communities', textbook => 'Textbook courses', + placement => 'Placement tests', ); return %titles; } @@ -4874,6 +5869,7 @@ sub courserequest_titles { unofficial => 'Unofficial', community => 'Communities', textbook => 'Textbook', + placement => 'Placement tests', norequest => 'Not allowed', approval => 'Approval by Dom. Coord.', validate => 'With validation', @@ -4964,7 +5960,7 @@ sub print_usercreation { } $datatable .= '<tr'.$css_class.'>'. '<td><span class="LC_nobreak">'.$lt{$item}. - '</span></td><td align="right">'; + '</span></td><td style="text-align: right">'; my @options = ('any'); if (ref($rules) eq 'HASH') { if (keys(%{$rules}) > 0) { @@ -5086,7 +6082,7 @@ sub print_selfcreation { ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked, \%choices,$itemcount,$onclick); $$rowtotal += $itemcount; - + if (ref($usertypes) eq 'HASH') { if (keys(%{$usertypes}) > 0) { $datatable .= &insttypes_row($createsettings,$types,$usertypes, @@ -5104,7 +6100,7 @@ sub print_selfcreation { $datatable .= '<tr'.$css_class.'>'. '<td class="LC_left_item">'.&mt('Mapping of Shibboleth environment variable names to user data fields (SSO auth)').'</td>'. '<td class="LC_left_item">'."\n". - '<table>'."\n"; + '<table><tr><td>'."\n"; for (my $i=0; $i<@fields; $i++) { $rem = $i%($numperrow); if ($rem == 0) { @@ -5223,7 +6219,7 @@ sub print_selfcreation { my $currstyle = 'display:none'; if (grep(/^\Q$status\E$/,@ordered)) { $currstyle = $rowstyle; - $hidden = 0; + $hidden = 0; } $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain, $emailrules,$emailruleorder,$settings,$status,$rowid, @@ -5250,8 +6246,8 @@ sub print_selfcreation { foreach my $status (@posstypes) { my $rowid = $classprefix.$status; my $datarowstyle = 'display:none'; - if (grep(/^\Q$status\E$/,@ordered)) { - $datarowstyle = $rowstyle; + if (grep(/^\Q$status\E$/,@ordered)) { + $datarowstyle = $rowstyle; } $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings, $numinrow,$$rowtotal,\%usertypeshash,$infofields, @@ -5353,7 +6349,7 @@ function toggleEmailOptions(form,radio,p document.getElementById(altprefix+'_inst_'+status).style.display = 'none'; document.getElementById(altprefix+'_noninst_'+status).style.display = 'none'; if (curr == 'custom') { - if (prefix) { + if (prefix) { document.getElementById(prefix+'_'+status).style.display = 'inline'; } } else if (curr == 'inst') { @@ -5376,10 +6372,10 @@ ENDSCRIPT sub noninst_users { my ($processing,$emailverified,$emailoptions,$emaildomain,$emailrules, - $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_; + $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_; my $class = 'LC_left_item'; if ($css_class) { - $css_class = ' class="'.$css_class.'"'; + $css_class = ' class="'.$css_class.'"'; } if ($rowid) { $rowid = ' id="'.$rowid.'"'; @@ -5394,10 +6390,10 @@ sub noninst_users { $description = &mt('Requests for: [_1] (status self-reported)',$typetitle); } $output = '<tr'.$css_class.$rowid.$rowstyle.'>'. - "<td>$description</td>\n". + "<td>$description</td>\n". '<td class="'.$class.'" colspan="2">'. '<table><tr>'; - my %headers = &Apache::lonlocal::texthash( + my %headers = &Apache::lonlocal::texthash( approve => 'Processing', email => 'E-mail', username => 'Username', @@ -5407,7 +6403,7 @@ sub noninst_users { } $output .= '</tr><tr>'; foreach my $item ('approve','email','username') { - $output .= '<td valign="top">'; + $output .= '<td style="vertical-align: top">'; my (%choices,@options,$hashref,$defoption,$name,$onclick,$hascustom); if ($item eq 'approve') { %choices = &Apache::lonlocal::texthash ( @@ -5522,7 +6518,7 @@ sub noninst_users { my $value; if (ref($emaildomain) eq 'HASH') { if (ref($emaildomain->{$type}) eq 'HASH') { - $value = $emaildomain->{$type}->{$option}; + $value = $emaildomain->{$type}->{$option}; } } if ($value eq '') { @@ -5542,7 +6538,6 @@ sub noninst_users { } $output .= '</td>'."\n"; } - } $output .= "</tr></table></td></tr>\n"; return $output; } @@ -5550,7 +6545,7 @@ sub noninst_users { sub captcha_choice { my ($context,$settings,$itemcount,$customcss,$rowstyle) = @_; my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext, - $vertext,$currver); + $vertext,$currver); my %lt = &captcha_phrases(); $keyentry = 'hidden'; if ($context eq 'cancreate') { @@ -5889,7 +6884,7 @@ sub print_defaults { 1 => 'Yes, allow login then update passwd file using default cost (if higher)', 2 => 'Yes, disallow login if stored cost is less than domain default', ); - $datatable .= '<table width="100%">'; + $datatable .= '<table wisth="100%">'; foreach my $option (@options) { my $checked = ' '; my $onclick; @@ -5907,7 +6902,7 @@ sub print_defaults { $datatable .= '</table>'; } else { $datatable .= '<input type="text" name="'.$item.'" value="'. - $defaults{$item}.'" size="3" onblur="javascript:warnIntAuth(this);" />'; + $defaults{$item}.'" size="3" onblur="javascript:warnIntAuth(this);" />'; } $datatable .= '</td></tr>'; $rownum ++; @@ -5936,7 +6931,7 @@ sub print_defaults { $datatable .= '</select> '.&mt('Internal ID:').' <b>'.$item.'</b> '. '<input type="checkbox" name="inststatus_delete" value="'.$item.'" />'. &mt('delete').'</span></td>'. - '<td class="LC_left_item"><span class="LC_nobreak">'.&mt('Name displayed:'). + '<td class="LC_left_item" colspan="2"><span class="LC_nobreak">'.&mt('Name displayed:'). '<input type="text" size="20" name="inststatus_title_'.$item.'" value="'.$title.'" />'. '</span></td></tr>'; } @@ -5955,7 +6950,7 @@ sub print_defaults { $datatable .= '</select> '.&mt('Internal ID:'). '<input type="text" size="10" name="addinststatus" value="" />'. ' '.&mt('(new)'). - '</span></td><td class="LC_left_item"><span class="LC_nobreak">'. + '</span></td><td class="LC_left_item" colspan="2"><span class="LC_nobreak">'. &mt('Name displayed:'). '<input type="text" size="20" name="addinststatus_title" value="" /></span></td>'. '</tr>'."\n"; @@ -6120,7 +7115,7 @@ sub print_scantronformat { } $datatable .= '</span></td>'; if (keys(%error) == 0) { - $datatable .= '<td valign="bottom">'; + $datatable .= '<td style="vertical-align: bottom">'; if (!$switchserver) { $datatable .= &mt('Upload:').'<br />'; } @@ -6219,7 +7214,7 @@ sub print_coursecategories { '<input type="radio" name="coursecat_'.$item.'" value="'.$type.'"'.$ischecked. ' />'.$lt{$type}.'</label> '; } - $datatable .= '</span></td></tr>'; + $datatable .= '</td></tr>'; $itemcount ++; } $$rowtotal += $itemcount; @@ -6232,6 +7227,10 @@ sub print_coursecategories { my $toggle_catscomm_dom = ' checked="checked" '; my $can_catcomm_comm = ' '; my $can_catcomm_dom = ' checked="checked" '; + my $toggle_catsplace_place = ' '; + my $toggle_catsplace_dom = ' checked="checked" '; + my $can_catplace_place = ' '; + my $can_catplace_dom = ' checked="checked" '; if (ref($settings) eq 'HASH') { if ($settings->{'togglecats'} eq 'crs') { @@ -6250,17 +7249,28 @@ sub print_coursecategories { $can_catcomm_comm = $can_catcomm_dom; $can_catcomm_dom = ' '; } + if ($settings->{'togglecatsplace'} eq 'place') { + $toggle_catsplace_place = $toggle_catsplace_dom; + $toggle_catsplace_dom = ' '; + } + if ($settings->{'categorizeplace'} eq 'place') { + $can_catplace_place = $can_catplace_dom; + $can_catplace_dom = ' '; + } } my %title = &Apache::lonlocal::texthash ( - togglecats => 'Show/Hide a course in catalog', - togglecatscomm => 'Show/Hide a community in catalog', - categorize => 'Assign a category to a course', - categorizecomm => 'Assign a category to a community', + togglecats => 'Show/Hide a course in catalog', + togglecatscomm => 'Show/Hide a community in catalog', + togglecatsplace => 'Show/Hide a placement test in catalog', + categorize => 'Assign a category to a course', + categorizecomm => 'Assign a category to a community', + categorizeplace => 'Assign a category to a placement test', ); my %level = &Apache::lonlocal::texthash ( - dom => 'Set in Domain', - crs => 'Set in Course', - comm => 'Set in Community', + dom => 'Set in Domain', + crs => 'Set in Course', + comm => 'Set in Community', + place => 'Set in Placement Test', ); $datatable = '<tr class="LC_odd_row">'. '<td>'.$title{'togglecats'}.'</td>'. @@ -6290,8 +7300,22 @@ sub print_coursecategories { $can_catcomm_dom.' value="dom" />'.$level{'dom'}.'</label> '. '<label><input type="radio" name="categorizecomm"'. $can_catcomm_comm.'value="comm" />'.$level{'comm'}.'</label></span></td>'. + '</tr><tr>'. + '<td>'.$title{'togglecatsplace'}.'</td>'. + '<td class="LC_right_item"><span class="LC_nobreak"><label>'. + '<input type="radio" name="togglecatsplace"'. + $toggle_catsplace_dom.' value="dom" />'.$level{'dom'}.'</label> '. + '<label><input type="radio" name="togglecatscomm"'. + $toggle_catsplace_place.' value="comm" />'.$level{'place'}.'</label></span></td>'. + '</tr><tr>'. + '<td>'.$title{'categorizeplace'}.'</td>'. + '<td class="LC_right_item"><span class="LC_nobreak">'. + '<label><input type="radio" name="categorizeplace"'. + $can_catplace_dom.' value="dom" />'.$level{'dom'}.'</label> '. + '<label><input type="radio" name="categorizeplace"'. + $can_catplace_place.'value="place" />'.$level{'place'}.'</label></span></td>'. '</tr>'; - $$rowtotal += 4; + $$rowtotal += 6; } else { my $css_class; my $itemcount = 1; @@ -6316,12 +7340,15 @@ sub print_coursecategories { my %default_names = ( instcode => &mt('Official courses'), communities => &mt('Communities'), + placement => &mt('Placement Tests'), ); if ((!grep(/^instcode$/,@{$cats[0]})) || ($cathash->{'instcode::0'} eq '') || (!grep(/^communities$/,@{$cats[0]})) || - ($cathash->{'communities::0'} eq '')) { + ($cathash->{'communities::0'} eq '') || + (!grep(/^placement$/,@{$cats[0]})) || + ($cathash->{'placement::0'} eq '')) { $maxnum ++; } my $lastidx; @@ -6342,7 +7369,7 @@ sub print_coursecategories { $datatable .= '<option value="'.$k.'"'.$selstr.'>'.$vpos.'</option>'; } $datatable .= '</select></span></td><td>'; - if ($parent eq 'instcode' || $parent eq 'communities') { + if ($parent eq 'instcode' || $parent eq 'communities' || $parent eq 'placement') { $datatable .= '<span class="LC_nobreak">' .$default_names{$parent}.'</span>'; if ($parent eq 'instcode') { @@ -6365,7 +7392,7 @@ sub print_coursecategories { $datatable .= '<label><input type="radio" name="' .$parent.'" value="0" />' .&mt('Do not display').'</label></span>'; - if ($parent eq 'communities') { + if (($parent eq 'communities') || ($parent eq 'placement')) { $datatable .= '</td></tr></table>'; } $datatable .= '</td>'; @@ -6397,7 +7424,7 @@ sub print_coursecategories { .'<input type="text" size="20" name="addcategory_name" value="" /></td>' .'</tr>'."\n"; $itemcount ++; - foreach my $default ('instcode','communities') { + foreach my $default ('instcode','communities','placement') { if ((!grep(/^\Q$default\E$/,@{$cats[0]})) || ($cathash->{$default.'::0'} eq '')) { $css_class = $itemcount%2?' class="LC_odd_row"':''; my $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','$lastidx'".');"'; @@ -6430,7 +7457,7 @@ sub print_coursecategories { $datatable .= &initialize_categories($itemcount); } } else { - $datatable .= '<tr><td class="LC_right_item">'.$hdritem->{'header'}->[1]->{'col2'}.'</td></tr>' + $datatable .= '<td class="LC_right_item">'.$hdritem->{'header'}->[1]->{'col2'}.'</td>' .&initialize_categories($itemcount); } $$rowtotal += $itemcount; @@ -6478,7 +7505,7 @@ sub print_serverstatuses { '<span class="LC_nobreak">'. '<input type="text" name="'.$type.'_machines" '. 'value="'.$machineaccess{$type}.'" size="10" />'. - '</span></td></tr>'."\n"; + '</td></tr>'."\n"; } $$rowtotal += $rownum; return $datatable; @@ -6486,9 +7513,9 @@ sub print_serverstatuses { sub serverstatus_pages { return ('userstatus','lonstatus','loncron','server-status','codeversions', - 'checksums','clusterstatus','metadata_keywords','metadata_harvest', - 'takeoffline','takeonline','showenv','toggledebug','ping','domconf', - 'uniquecodes','diskusage','coursecatalog'); + 'checksums','clusterstatus','certstatus','metadata_keywords', + 'metadata_harvest','takeoffline','takeonline','showenv','toggledebug', + 'ping','domconf','uniquecodes','diskusage','coursecatalog'); } sub defaults_javascript { @@ -6610,9 +7637,11 @@ sub coursecategories_javascript { } my $instcode_reserved = &mt('The name: [_1] is a reserved category.','"instcode"'); my $communities_reserved = &mt('The name: [_1] is a reserved category.','"communities"'); + my $placement_reserved = &mt('The name: [_1] is a reserved category.','"placement"'); my $choose_again = "\n".&mt('Please use a different name for the new top level category.'); &js_escape(\$instcode_reserved); &js_escape(\$communities_reserved); + &js_escape(\$placement_reserved); &js_escape(\$choose_again); $output = <<"ENDSCRIPT"; <script type="text/javascript"> @@ -6682,6 +7711,10 @@ function categoryCheck(form) { alert('$communities_reserved\\n$choose_again'); return false; } + if (form.elements['addcategory_name'].value == 'placement') { + alert('$placement_reserved\\n$choose_again'); + return false; + } return true; } @@ -6698,13 +7731,14 @@ sub initialize_categories { my %default_names = ( instcode => 'Official courses (with institutional codes)', communities => 'Communities', + placement => 'Placement Tests', ); my $select0 = ' selected="selected"'; my $select1 = ''; - foreach my $default ('instcode','communities') { + foreach my $default ('instcode','communities','placement') { $css_class = $itemcount%2?' class="LC_odd_row"':''; - $chgstr = ' onchange="javascript:reorderCats(this.form,'."'','$default"."_pos','0'".');"'; - if ($default eq 'communities') { + $chgstr = ' onchange="javascript:reorderCats(this.form,'."'',$default"."_pos','0'".');"'; + if (($default eq 'communities') || ($default eq 'placement')) { $select1 = $select0; $select0 = ''; } @@ -6728,9 +7762,8 @@ sub initialize_categories { .'<option value="0">1</option>' .'<option value="1">2</option>' .'<option value="2" selected="selected">3</option></select> ' - .&mt('Add category').'</span></td><tda<span class="LC_nobreak">>'.&mt('Name:') - .' <input type="text" size="20" name="addcategory_name" value="" /></span>' - .'</td></tr>'; + .&mt('Add category').'</td><td>'.&mt('Name:') + .' <input type="text" size="20" name="addcategory_name" value="" /></td></tr>'; return $datatable; } @@ -6785,7 +7818,7 @@ sub build_category_rows { pop(@{$path}); } } else { - $text .= &mt('Add subcategory:').' </span><input type="text" size="20" name="addcategory_name_'; + $text .= &mt('Add subcategory:').' </span><input type="textbox" size="20" name="addcategory_name_'; if ($j == $numchildren) { $text .= $name; } else { @@ -6808,7 +7841,7 @@ sub build_category_rows { my $colspan; if ($parent ne 'instcode') { $colspan = $maxdepth - $depth - 1; - $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="text" size="20" name="subcat_'.$name.'" value="" /></td>'; + $text .= '<td colspan="'.$colspan.'">'.&mt('Add subcategory:').'<input type="textbox" size="20" name="subcat_'.$name.'" value="" /></td>'; } } } @@ -6876,7 +7909,6 @@ sub modifiable_userdata_row { if ($rowid) { $rowid = ' id="'.$rowid.'"'; } - $output = '<tr '.$css_class.$rowid.'>'. '<td><span class="LC_nobreak">'.$rolename.'</span></td>'. '<td class="LC_left_item" colspan="2"><table>'; @@ -6911,7 +7943,7 @@ sub modifiable_userdata_row { } } } - + my $total = scalar(@fields); for (my $i=0; $i<$total; $i++) { $rem = $i%($numinrow); @@ -6980,6 +8012,7 @@ sub insttypes_row { statustocreate => 'Institutional affiliation(s) able to create own account (login/SSO)', lockablenames => 'User preference to lock name', selfassign => 'Self-reportable affiliations', + overrides => "Override domain's helpdesk settings based on requester's affiliation", ); my $showdom; if ($context eq 'cansearch') { @@ -7026,6 +8059,10 @@ sub insttypes_row { if (grep(/^\Q$types->[$i]\E$/,@{$settings->{$context}})) { $check = ' checked="checked" '; } + } elsif (ref($settings->{$context}) eq 'HASH') { + if (ref($settings->{$context}->{$types->[$i]}) eq 'HASH') { + $check = ' checked="checked" '; + } } elsif ($context eq 'statustocreate') { $check = ' checked="checked" '; } @@ -7033,36 +8070,45 @@ sub insttypes_row { $output .= '<td class="LC_left_item">'. '<span class="LC_nobreak"><label>'. '<input type="checkbox" name="'.$context.'" '. - 'value="'.$types->[$i].'"'.$check.$onclick.'/>'. + 'value="'.$types->[$i].'"'.$check.$onclick.' />'. $usertypes->{$types->[$i]}.'</label></span></td>'; } } $rem = @{$types}%($numinrow); } my $colsleft = $numinrow - $rem; - if ($rem == 0) { - $output .= '<tr>'; - } - if ($colsleft > 1) { - $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; + if ($context eq 'overrides') { + if ($colsleft > 1) { + $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; + } else { + $output .= '<td class="LC_left_item">'; + } + $output .= ' '; } else { - $output .= '<td class="LC_left_item">'; - } - my $defcheck = ' '; - if (ref($settings) eq 'HASH') { - if (ref($settings->{$context}) eq 'ARRAY') { - if (grep(/^default$/,@{$settings->{$context}})) { + if (($rem == 0) && (@{$types} > 0)) { + $output .= '<tr>'; + } + if ($colsleft > 1) { + $output .= '<td colspan="'.$colsleft.'" class="LC_left_item">'; + } else { + $output .= '<td class="LC_left_item">'; + } + my $defcheck = ' '; + if (ref($settings) eq 'HASH') { + if (ref($settings->{$context}) eq 'ARRAY') { + if (grep(/^default$/,@{$settings->{$context}})) { + $defcheck = ' checked="checked" '; + } + } elsif ($context eq 'statustocreate') { $defcheck = ' checked="checked" '; } - } elsif ($context eq 'statustocreate') { - $defcheck = ' checked="checked" '; } + $output .= '<span class="LC_nobreak"><label>'. + '<input type="checkbox" name="'.$context.'" '. + 'value="default"'.$defcheck.$onclick.' />'. + $othertitle.'</label></span>'; } - $output .= '<span class="LC_nobreak"><label>'. - '<input type="checkbox" name="'.$context.'" '. - 'value="default"'.$defcheck.$onclick.'/>'. - $othertitle.'</label></span></td>'. - '</tr></table></td></tr>'; + $output .= '</td></tr></table></td></tr>'; return $output; } @@ -7969,7 +9015,7 @@ sub display_colorchgs { } else { my $newitem = $confhash->{$role}{$item}; if ($key eq 'images') { - $newitem = '<img src="'.$confhash->{$role}{$item}.'" alt="'.$choices{$item}.'" valign="bottom" />'; + $newitem = '<img src="'.$confhash->{$role}{$item}.'" alt="'.$choices{$item}.'" style="vertical-align: bottom" />'; } $resulttext .= '<li>'.&mt("$choices{$item} set to [_1]",$newitem).'</li>'; } @@ -8051,7 +9097,7 @@ sub check_authorstatus { sub publishlogo { my ($r,$action,$formname,$dom,$confname,$subdir,$thumbwidth,$thumbheight,$savefileas) = @_; - my ($output,$fname,$logourl); + my ($output,$fname,$logourl,$madethumb); if ($action eq 'upload') { $fname=$env{'form.'.$formname.'.filename'}; chop($env{'form.'.$formname}); @@ -8180,6 +9226,7 @@ $env{'user.name'}.':'.$env{'user.domain' $r->set_handlers('PerlCleanupHandler' => [\¬ifysubscribed,@{$handlers}]); $registered_cleanup=1; } + $madethumb = 1; } else { print $logfile "\nUnable to write ".$copyfile. ':'.$!."\n"; @@ -8192,7 +9239,7 @@ $env{'user.name'}.':'.$env{'user.domain' $output = $versionresult; } } - return ($output,$logourl); + return ($output,$logourl,$madethumb); } sub logo_versioning { @@ -8346,7 +9393,7 @@ sub modify_quotas { $context = $action; } if ($context eq 'requestcourses') { - @usertools = ('official','unofficial','community','textbook'); + @usertools = ('official','unofficial','community','textbook','placement'); @options =('norequest','approval','validate','autolimit'); %validations = &Apache::lonnet::auto_courserequest_checks($dom); %titles = &courserequest_titles(); @@ -8395,7 +9442,7 @@ sub modify_quotas { my @approvalnotify = &Apache::loncommon::get_env_multiple('form.'.$context.'notifyapproval'); @approvalnotify = sort(@approvalnotify); $confhash{'notify'}{'approval'} = join(',',@approvalnotify); - my @crstypes = ('official','unofficial','community','textbook'); + my @crstypes = ('official','unofficial','community','textbook','placement'); my @hasuniquecode = &Apache::loncommon::get_env_multiple('form.uniquecode'); foreach my $type (@hasuniquecode) { if (grep(/^\Q$type\E$/,@crstypes)) { @@ -8517,7 +9564,7 @@ sub modify_quotas { &Apache::lonnet::logthis($error); $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; } - } + } } elsif ($domconfig{$action}{$type}{$key}{'image'}) { $confhash{$type}{$key}{'image'} = $domconfig{$action}{$type}{$key}{'image'}; @@ -9069,6 +10116,616 @@ sub process_textbook_image { return ($url,$error); } +sub modify_ltitools { + my ($r,$dom,$action,$lastactref,%domconfig) = @_; + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); + my ($newid,@allpos,%changes,%confhash,%encconfig,$errors,$resulttext); + my $confname = $dom.'-domainconfig'; + my $servadm = $r->dir_config('lonAdmEMail'); + my ($configuserok,$author_ok,$switchserver) = &config_check($dom,$confname,$servadm); + my (%posslti,%possfield); + my @courseroles = ('cc','in','ta','ep','st'); + my @ltiroles = qw(Instructor ContentDeveloper TeachingAssistant Learner); + map { $posslti{$_} = 1; } @ltiroles; + my @allfields = ('fullname','firstname','lastname','email','user','roles'); + map { $possfield{$_} = 1; } @allfields; + my %lt = <itools_names(); + if ($env{'form.ltitools_add'}) { + my $title = $env{'form.ltitools_add_title'}; + $title =~ s/(`)/'/g; + ($newid,my $error) = &get_ltitools_id($dom,$title); + if ($newid) { + my $position = $env{'form.ltitools_add_pos'}; + $position =~ s/\D+//g; + if ($position ne '') { + $allpos[$position] = $newid; + } + $changes{$newid} = 1; + foreach my $item ('title','url','key','secret') { + $env{'form.ltitools_add_'.$item} =~ s/(`)/'/g; + if ($env{'form.ltitools_add_'.$item}) { + if (($item eq 'key') || ($item eq 'secret')) { + $encconfig{$newid}{$item} = $env{'form.ltitools_add_'.$item}; + } else { + $confhash{$newid}{$item} = $env{'form.ltitools_add_'.$item}; + } + } + } + if ($env{'form.ltitools_add_version'} eq 'LTI-1p0') { + $confhash{$newid}{'version'} = $env{'form.ltitools_add_version'}; + } + if ($env{'form.ltitools_add_msgtype'} eq 'basic-lti-launch-request') { + $confhash{$newid}{'msgtype'} = $env{'form.ltitools_add_msgtype'}; + } + foreach my $item ('width','height','linktext','explanation') { + $env{'form.ltitools_add_'.$item} =~ s/^\s+//; + $env{'form.ltitools_add_'.$item} =~ s/\s+$//; + if (($item eq 'width') || ($item eq 'height')) { + if ($env{'form.ltitools_add_'.$item} =~ /^\d+$/) { + $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item}; + } + } else { + if ($env{'form.ltitools_add_'.$item} ne '') { + $confhash{$newid}{'display'}{$item} = $env{'form.ltitools_add_'.$item}; + } + } + } + if ($env{'form.ltitools_add_target'} eq 'window') { + $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'}; + } elsif ($env{'form.ltitools_add_target'} eq 'tab') { + $confhash{$newid}{'display'}{'target'} = $env{'form.ltitools_add_target'}; + } else { + $confhash{$newid}{'display'}{'target'} = 'iframe'; + } + foreach my $item ('passback','roster') { + if ($env{'form.ltitools_'.$item.'_add'}) { + $confhash{$newid}{$item} = 1; + if ($env{'form.ltitools_'.$item.'valid_add'} ne '') { + my $lifetime = $env{'form.ltitools_'.$item.'valid_add'}; + $lifetime =~ s/^\s+|\s+$//g; + if ($lifetime =~ /^\d+\.?\d*$/) { + $confhash{$newid}{$item.'valid'} = $lifetime; + } + } + } + } + if ($env{'form.ltitools_add_image.filename'} ne '') { + my ($imageurl,$error) = + &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$newid, + $configuserok,$switchserver,$author_ok); + if ($imageurl) { + $confhash{$newid}{'image'} = $imageurl; + } + if ($error) { + &Apache::lonnet::logthis($error); + $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; + } + } + my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_add_fields'); + foreach my $field (@fields) { + if ($possfield{$field}) { + if ($field eq 'roles') { + foreach my $role (@courseroles) { + my $choice = $env{'form.ltitools_add_roles_'.$role}; + if (($choice ne '') && ($posslti{$choice})) { + $confhash{$newid}{'roles'}{$role} = $choice; + if ($role eq 'cc') { + $confhash{$newid}{'roles'}{'co'} = $choice; + } + } + } + } else { + $confhash{$newid}{'fields'}{$field} = 1; + } + } + } + my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig'); + foreach my $item (@courseconfig) { + $confhash{$newid}{'crsconf'}{$item} = 1; + } + if ($env{'form.ltitools_add_custom'}) { + my $name = $env{'form.ltitools_add_custom_name'}; + my $value = $env{'form.ltitools_add_custom_value'}; + $value =~ s/(`)/'/g; + $name =~ s/(`)/'/g; + $confhash{$newid}{'custom'}{$name} = $value; + } + } else { + my $error = &mt('Failed to acquire unique ID for new external tool'); + $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; + } + } + if (ref($domconfig{$action}) eq 'HASH') { + my %deletions; + my @todelete = &Apache::loncommon::get_env_multiple('form.ltitools_del'); + if (@todelete) { + map { $deletions{$_} = 1; } @todelete; + } + my %customadds; + my @newcustom = &Apache::loncommon::get_env_multiple('form.ltitools_customadd'); + if (@newcustom) { + map { $customadds{$_} = 1; } @newcustom; + } + my %imgdeletions; + my @todeleteimages = &Apache::loncommon::get_env_multiple('form.ltitools_image_del'); + if (@todeleteimages) { + map { $imgdeletions{$_} = 1; } @todeleteimages; + } + my $maxnum = $env{'form.ltitools_maxnum'}; + for (my $i=0; $i<=$maxnum; $i++) { + my $itemid = $env{'form.ltitools_id_'.$i}; + $itemid =~ s/\D+//g; + if (ref($domconfig{$action}{$itemid}) eq 'HASH') { + if ($deletions{$itemid}) { + if ($domconfig{$action}{$itemid}{'image'}) { + #FIXME need to obsolete item in RES space + } + $changes{$itemid} = $domconfig{$action}{$itemid}{'title'}; + next; + } else { + my $newpos = $env{'form.ltitools_'.$itemid}; + $newpos =~ s/\D+//g; + foreach my $item ('title','url') { + $confhash{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i}; + if ($domconfig{$action}{$itemid}{$item} ne $confhash{$itemid}{$item}) { + $changes{$itemid} = 1; + } + } + foreach my $item ('key','secret') { + $encconfig{$itemid}{$item} = $env{'form.ltitools_'.$item.'_'.$i}; + if ($domconfig{$action}{$itemid}{$item} ne $encconfig{$itemid}{$item}) { + $changes{$itemid} = 1; + } + } + if ($env{'form.ltitools_version_'.$i} eq 'LTI-1p0') { + $confhash{$itemid}{'version'} = $env{'form.ltitools_version_'.$i}; + } + if ($env{'form.ltitools_msgtype_'.$i} eq 'basic-lti-launch-request') { + $confhash{$itemid}{'msgtype'} = $env{'form.ltitools_msgtype_'.$i}; + } + foreach my $size ('width','height') { + $env{'form.ltitools_'.$size.'_'.$i} =~ s/^\s+//; + $env{'form.ltitools_'.$size.'_'.$i} =~ s/\s+$//; + if ($env{'form.ltitools_'.$size.'_'.$i} =~ /^\d+$/) { + $confhash{$itemid}{'display'}{$size} = $env{'form.ltitools_'.$size.'_'.$i}; + if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'display'}{$size} ne $confhash{$itemid}{'display'}{$size}) { + $changes{$itemid} = 1; + } + } else { + $changes{$itemid} = 1; + } + } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'display'}{$size} ne '') { + $changes{$itemid} = 1; + } + } + } + foreach my $item ('linktext','explanation') { + $env{'form.ltitools_'.$item.'_'.$i} =~ s/^\s+//; + $env{'form.ltitools_'.$item.'_'.$i} =~ s/\s+$//; + if ($env{'form.ltitools_'.$item.'_'.$i} ne '') { + $confhash{$itemid}{'display'}{$item} = $env{'form.ltitools_'.$item.'_'.$i}; + if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'display'}{$item} ne $confhash{$itemid}{'display'}{$item}) { + $changes{$itemid} = 1; + } + } else { + $changes{$itemid} = 1; + } + } elsif (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'display'}{$item} ne '') { + $changes{$itemid} = 1; + } + } + } + if ($env{'form.ltitools_target_'.$i} eq 'window') { + $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i}; + } elsif ($env{'form.ltitools_target_'.$i} eq 'tab') { + $confhash{$itemid}{'display'}{'target'} = $env{'form.ltitools_target_'.$i}; + } else { + $confhash{$itemid}{'display'}{'target'} = 'iframe'; + } + if (ref($domconfig{$action}{$itemid}{'display'}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'display'}{'target'} ne $confhash{$itemid}{'display'}{'target'}) { + $changes{$itemid} = 1; + } + } else { + $changes{$itemid} = 1; + } + foreach my $extra ('passback','roster') { + if ($env{'form.ltitools_'.$extra.'_'.$i}) { + $confhash{$itemid}{$extra} = 1; + if ($env{'form.ltitools_'.$extra.'valid_'.$i} ne '') { + my $lifetime = $env{'form.ltitools_'.$extra.'valid_add'}; + $lifetime =~ s/^\s+|\s+$//g; + if ($lifetime =~ /^\d+\.?\d*$/) { + $confhash{$itemid}{$extra.'valid'} = $lifetime; + } + } + } + if ($domconfig{$action}{$itemid}{$extra} ne $confhash{$itemid}{$extra}) { + $changes{$itemid} = 1; + } + if ($domconfig{$action}{$itemid}{$extra.'valid'} ne $confhash{$itemid}{$extra.'valid'}) { + $changes{$itemid} = 1; + } + } + my @courseconfig = &Apache::loncommon::get_env_multiple('form.ltitools_courseconfig_'.$i); + foreach my $item ('label','title','target','linktext','explanation','append') { + if (grep(/^\Q$item\E$/,@courseconfig)) { + $confhash{$itemid}{'crsconf'}{$item} = 1; + if (ref($domconfig{$action}{$itemid}{'crsconf'}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'crsconf'}{$item} ne $confhash{$itemid}{'crsconf'}{$item}) { + $changes{$itemid} = 1; + } + } else { + $changes{$itemid} = 1; + } + } + } + my @fields = &Apache::loncommon::get_env_multiple('form.ltitools_fields_'.$i); + foreach my $field (@fields) { + if ($possfield{$field}) { + if ($field eq 'roles') { + foreach my $role (@courseroles) { + my $choice = $env{'form.ltitools_roles_'.$role.'_'.$i}; + if (($choice ne '') && ($posslti{$choice})) { + $confhash{$itemid}{'roles'}{$role} = $choice; + if ($role eq 'cc') { + $confhash{$itemid}{'roles'}{'co'} = $choice; + } + } + if (ref($domconfig{$action}{$itemid}{'roles'}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'roles'}{$role} ne $confhash{$itemid}{'roles'}{$role}) { + $changes{$itemid} = 1; + } + } elsif ($confhash{$itemid}{'roles'}{$role}) { + $changes{$itemid} = 1; + } + } + } else { + $confhash{$itemid}{'fields'}{$field} = 1; + if (ref($domconfig{$action}{$itemid}{'fields'}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'fields'}{$field} ne $confhash{$itemid}{'fields'}{$field}) { + $changes{$itemid} = 1; + } + } else { + $changes{$itemid} = 1; + } + } + } + } + $allpos[$newpos] = $itemid; + } + if ($imgdeletions{$itemid}) { + $changes{$itemid} = 1; + #FIXME need to obsolete item in RES space + } elsif ($env{'form.ltitools_image_'.$i.'.filename'}) { + my ($imgurl,$error) = &process_ltitools_image($r,$dom,$confname,'ltitools_image_'.$i, + $itemid,$configuserok,$switchserver, + $author_ok); + if ($imgurl) { + $confhash{$itemid}{'image'} = $imgurl; + $changes{$itemid} = 1; + } + if ($error) { + &Apache::lonnet::logthis($error); + $errors .= '<li><span class="LC_error">'.$error.'</span></li>'; + } + } elsif ($domconfig{$action}{$itemid}{'image'}) { + $confhash{$itemid}{'image'} = + $domconfig{$action}{$itemid}{'image'}; + } + if ($customadds{$i}) { + my $name = $env{'form.ltitools_custom_name_'.$i}; + $name =~ s/(`)/'/g; + $name =~ s/^\s+//; + $name =~ s/\s+$//; + my $value = $env{'form.ltitools_custom_value_'.$i}; + $value =~ s/(`)/'/g; + $value =~ s/^\s+//; + $value =~ s/\s+$//; + if ($name ne '') { + $confhash{$itemid}{'custom'}{$name} = $value; + $changes{$itemid} = 1; + } + } + my %customdels; + my @customdeletions = &Apache::loncommon::get_env_multiple('form.ltitools_customdel_'.$i); + if (@customdeletions) { + $changes{$itemid} = 1; + } + map { $customdels{$_} = 1; } @customdeletions; + if (ref($domconfig{$action}{$itemid}{'custom'}) eq 'HASH') { + foreach my $key (keys(%{$domconfig{$action}{$itemid}{'custom'}})) { + unless ($customdels{$key}) { + if ($env{'form.ltitools_customval_'.$key.'_'.$i} ne '') { + $confhash{$itemid}{'custom'}{$key} = $env{'form.ltitools_customval_'.$key.'_'.$i}; + } + if ($domconfig{$action}{$itemid}{'custom'}{$key} ne $env{'form.ltitools_customval_'.$key.'_'.$i}) { + $changes{$itemid} = 1; + } + } + } + } + unless ($changes{$itemid}) { + foreach my $key (keys(%{$domconfig{$action}{$itemid}})) { + if (ref($domconfig{$action}{$itemid}{$key}) eq 'HASH') { + if (ref($confhash{$itemid}{$key}) eq 'HASH') { + foreach my $innerkey (keys(%{$domconfig{$action}{$itemid}{$key}})) { + unless (exists($confhash{$itemid}{$key}{$innerkey})) { + $changes{$itemid} = 1; + last; + } + } + } elsif (keys(%{$domconfig{$action}{$itemid}{$key}}) > 0) { + $changes{$itemid} = 1; + } + } + last if ($changes{$itemid}); + } + } + } + } + } + if (@allpos > 0) { + my $idx = 0; + foreach my $itemid (@allpos) { + if ($itemid ne '') { + $confhash{$itemid}{'order'} = $idx; + if (ref($domconfig{$action}) eq 'HASH') { + if (ref($domconfig{$action}{$itemid}) eq 'HASH') { + if ($domconfig{$action}{$itemid}{'order'} ne $idx) { + $changes{$itemid} = 1; + } + } + } + $idx ++; + } + } + } + my %ltitoolshash = ( + $action => { %confhash } + ); + my $putresult = &Apache::lonnet::put_dom('configuration',\%ltitoolshash, + $dom); + if ($putresult eq 'ok') { + my %ltienchash = ( + $action => { %encconfig } + ); + &Apache::lonnet::put_dom('encconfig',\%ltienchash,$dom); + if (keys(%changes) > 0) { + my $cachetime = 24*60*60; + my %ltiall = %confhash; + foreach my $id (keys(%ltiall)) { + if (ref($encconfig{$id}) eq 'HASH') { + foreach my $item ('key','secret') { + $ltiall{$id}{$item} = $encconfig{$id}{$item}; + } + } + } + &Apache::lonnet::do_cache_new('ltitools',$dom,\%ltiall,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'ltitools'} = 1; + } + $resulttext = &mt('Changes made:').'<ul>'; + my %bynum; + foreach my $itemid (sort(keys(%changes))) { + my $position = $confhash{$itemid}{'order'}; + $bynum{$position} = $itemid; + } + foreach my $pos (sort { $a <=> $b } keys(%bynum)) { + my $itemid = $bynum{$pos}; + if (ref($confhash{$itemid}) ne 'HASH') { + $resulttext .= '<li>'.&mt('Deleted: [_1]',$changes{$itemid}).'</li>'; + } else { + $resulttext .= '<li><b>'.$confhash{$itemid}{'title'}.'</b>'; + if ($confhash{$itemid}{'image'}) { + $resulttext .= ' '. + '<img src="'.$confhash{$itemid}{'image'}.'"'. + ' alt="'.&mt('Tool Provider icon').'" />'; + } + $resulttext .= '</li><ul>'; + my $position = $pos + 1; + $resulttext .= '<li>'.&mt('Order: [_1]',$position).'</li>'; + foreach my $item ('version','msgtype','url') { + if ($confhash{$itemid}{$item} ne '') { + $resulttext .= '<li>'.$lt{$item}.': '.$confhash{$itemid}{$item}.'</li>'; + } + } + if ($encconfig{$itemid}{'key'} ne '') { + $resulttext .= '<li>'.$lt{'key'}.': '.$encconfig{$itemid}{'key'}.'</li>'; + } + if ($encconfig{$itemid}{'secret'} ne '') { + $resulttext .= '<li>'.$lt{'secret'}.': '; + my $num = length($encconfig{$itemid}{'secret'}); + $resulttext .= ('*'x$num).'</li>'; + } + $resulttext .= '<li>'.&mt('Configurable in course:'); + my @possconfig = ('label','title','target','linktext','explanation','append'); + my $numconfig = 0; + if (ref($confhash{$itemid}{'crsconf'}) eq 'HASH') { + foreach my $item (@possconfig) { + if ($confhash{$itemid}{'crsconf'}{$item}) { + $numconfig ++; + $resulttext .= ' "'.$lt{'crs'.$item}.'"'; + } + } + } + if (!$numconfig) { + $resulttext .= &mt('None'); + } + $resulttext .= '</li>'; + foreach my $item ('passback','roster') { + $resulttext .= '<li>'.$lt{$item}.' '; + if ($confhash{$itemid}{$item}) { + $resulttext .= &mt('Yes'); + if ($confhash{$itemid}{$item.'valid'}) { + if ($item eq 'passback') { + $resulttext .= ' '.&mt('valid for at least [quant,_1,day] after launch', + $confhash{$itemid}{$item.'valid'}); + } else { + $resulttext .= ' '.&mt('valid for at least [quant,_1,second] after launch', + $confhash{$itemid}{$item.'valid'}); + } + } + } else { + $resulttext .= &mt('No'); + } + $resulttext .= '</li>'; + } + if (ref($confhash{$itemid}{'display'}) eq 'HASH') { + my $displaylist; + if ($confhash{$itemid}{'display'}{'target'}) { + $displaylist = &mt('Display target').': '. + $confhash{$itemid}{'display'}{'target'}.','; + } + foreach my $size ('width','height') { + if ($confhash{$itemid}{'display'}{$size}) { + $displaylist .= (' 'x2).$lt{$size}.': '. + $confhash{$itemid}{'display'}{$size}.','; + } + } + if ($displaylist) { + $displaylist =~ s/,$//; + $resulttext .= '<li>'.$displaylist.'</li>'; + } + foreach my $item ('linktext','explanation') { + if ($confhash{$itemid}{'display'}{$item}) { + $resulttext .= '<li>'.$lt{$item}.': '.$confhash{$itemid}{'display'}{$item}.'</li>'; + } + } + } + if (ref($confhash{$itemid}{'fields'}) eq 'HASH') { + my $fieldlist; + foreach my $field (@allfields) { + if ($confhash{$itemid}{'fields'}{$field}) { + $fieldlist .= (' 'x2).$lt{$field}.','; + } + } + if ($fieldlist) { + $fieldlist =~ s/,$//; + $resulttext .= '<li>'.&mt('Data sent').':'.$fieldlist.'</li>'; + } + } + if (ref($confhash{$itemid}{'roles'}) eq 'HASH') { + my $rolemaps; + foreach my $role (@courseroles) { + if ($confhash{$itemid}{'roles'}{$role}) { + $rolemaps .= (' 'x2).&Apache::lonnet::plaintext($role,'Course').'='. + $confhash{$itemid}{'roles'}{$role}.','; + } + } + if ($rolemaps) { + $rolemaps =~ s/,$//; + $resulttext .= '<li>'.&mt('Role mapping:').$rolemaps.'</li>'; + } + } + if (ref($confhash{$itemid}{'custom'}) eq 'HASH') { + my $customlist; + if (keys(%{$confhash{$itemid}{'custom'}})) { + foreach my $key (sort(keys(%{$confhash{$itemid}{'custom'}}))) { + $customlist .= $key.':'.$confhash{$itemid}{'custom'}{$key}.(' 'x2); + } + } + if ($customlist) { + $resulttext .= '<li>'.&mt('Custom items').': '.$customlist.'</li>'; + } + } + $resulttext .= '</ul></li>'; + } + } + $resulttext .= '</ul>'; + } else { + $resulttext = &mt('No changes made.'); + } + } else { + $errors .= '<li><span class="LC_error">'.&mt('Failed to save changes').'</span></li>'; + } + if ($errors) { + $resulttext .= &mt('The following errors occurred: ').'<ul>'. + $errors.'</ul>'; + } + return $resulttext; +} + +sub process_ltitools_image { + my ($r,$dom,$confname,$caller,$itemid,$configuserok,$switchserver,$author_ok) = @_; + my $filename = $env{'form.'.$caller.'.filename'}; + my ($error,$url); + my ($width,$height) = (21,21); + if ($configuserok eq 'ok') { + if ($switchserver) { + $error = &mt('Upload of Tool Provider (LTI) icon is not permitted to this server: [_1]', + $switchserver); + } elsif ($author_ok eq 'ok') { + my ($result,$imageurl,$madethumb) = + &publishlogo($r,'upload',$caller,$dom,$confname, + "ltitools/$itemid/icon",$width,$height); + if ($result eq 'ok') { + if ($madethumb) { + my ($path,$imagefile) = ($imageurl =~ m{^(.+)/([^/]+)$}); + my $imagethumb = "$path/tn-".$imagefile; + $url = $imagethumb; + } else { + $url = $imageurl; + } + } else { + $error = &mt("Upload of [_1] failed because an error occurred publishing the file in RES space. Error was: [_2].",$filename,$result); + } + } else { + $error = &mt("Upload of [_1] failed because an author role could not be assigned to a Domain Configuration user ([_2]) in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$author_ok); + } + } else { + $error = &mt("Upload of [_1] failed because a Domain Configuration user ([_2]) could not be created in domain: [_3]. Error was: [_4].",$filename,$confname,$dom,$configuserok); + } + return ($url,$error); +} + +sub get_ltitools_id { + my ($cdom,$title) = @_; + # get lock on ltitools db + my $lockhash = { + lock => $env{'user.name'}. + ':'.$env{'user.domain'}, + }; + my $tries = 0; + my $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom); + my ($id,$error); + + while (($gotlock ne 'ok') && ($tries<10)) { + $tries ++; + sleep (0.1); + $gotlock = &Apache::lonnet::newput_dom('ltitools',$lockhash,$cdom); + } + if ($gotlock eq 'ok') { + my %currids = &Apache::lonnet::dump_dom('ltitools',$cdom); + if ($currids{'lock'}) { + delete($currids{'lock'}); + if (keys(%currids)) { + my @curr = sort { $a <=> $b } keys(%currids); + if ($curr[-1] =~ /^\d+$/) { + $id = 1 + $curr[-1]; + } + } else { + $id = 1; + } + if ($id) { + unless (&Apache::lonnet::newput_dom('ltitools',{ $id => $title },$cdom) eq 'ok') { + $error = 'nostore'; + } + } else { + $error = 'nonumber'; + } + } + my $dellockoutcome = &Apache::lonnet::del_dom('ltitools',['lock'],$cdom); + } else { + $error = 'nolock'; + } + return ($id,$error); +} + sub modify_autoenroll { my ($dom,$lastactref,%domconfig) = @_; my ($resulttext,%changes); @@ -9654,7 +11311,7 @@ sub modify_contacts { my (%others,%to,%bcc,%includestr,%includeloc); my @contacts = ('supportemail','adminemail'); my @mailings = ('errormail','packagesmail','helpdeskmail','otherdomsmail', - 'lonstatusmail','requestsmail','updatesmail','idconflictsmail',hostipmail'); + 'lonstatusmail','requestsmail','updatesmail','idconflictsmail'); my @toggles = ('reporterrors','reportupdates'); my ($fields,$fieldtitles,$fieldoptions,$possoptions) = &helpform_fields(); foreach my $type (@mailings) { @@ -9694,17 +11351,57 @@ sub modify_contacts { my $value = $env{'form.helpform_'.$field}; $value =~ s/^\s+|\s+$//g; if (grep(/^\Q$value\E$/,@{$possoptions->{$field}})) { - $contacts_hash{contacts}{'helpform'}{$field} = $value; + $contacts_hash{'contacts'}{'helpform'}{$field} = $value; if ($field eq 'screenshot') { $env{'form.helpform_maxsize'} =~ s/^\s+|\s+$//g; if ($env{'form.helpform_maxsize'} =~ /^\d+\.?\d*$/) { - $contacts_hash{contacts}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'}; + $contacts_hash{'contacts'}{'helpform'}{'maxsize'} = $env{'form.helpform_maxsize'}; } } } } } } + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + my (@statuses,%usertypeshash,@overrides); + if ((ref($types) eq 'ARRAY') && (@{$types} > 0)) { + @statuses = @{$types}; + if (ref($usertypes) eq 'HASH') { + %usertypeshash = %{$usertypes}; + } + } + if (@statuses) { + my @possoverrides = &Apache::loncommon::get_env_multiple('form.overrides'); + foreach my $type (@possoverrides) { + if (($type ne '') && (grep(/^\Q$type\E$/,@statuses))) { + push(@overrides,$type); + } + } + if (@overrides) { + foreach my $type (@overrides) { + my @standard = &Apache::loncommon::get_env_multiple('form.override_'.$type); + foreach my $item (@contacts) { + if (grep(/^\Q$item\E$/,@standard)) { + $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 1; + $newsetting{'override_'.$type}{$item} = 1; + } else { + $contacts_hash{'contacts'}{'overrides'}{$type}{$item} = 0; + $newsetting{'override_'.$type}{$item} = 0; + } + } + $contacts_hash{'contacts'}{'overrides'}{$type}{'others'} = $env{'form.override_'.$type.'_others'}; + $contacts_hash{'contacts'}{'overrides'}{$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'}; + $newsetting{'override_'.$type}{'others'} = $env{'form.override_'.$type.'_others'}; + $newsetting{'override_'.$type}{'bcc'} = $env{'form.override_'.$type.'_bcc'}; + if (($env{'form.override_'.$type.'_includestr'} ne '') && ($env{'form.override_'.$type.'_includeloc'} =~ /^s|b$/)) { + $includestr{$type} = $env{'form.override_'.$type.'_includestr'}; + $includeloc{$type} = $env{'form.override_'.$type.'_includeloc'}; + $contacts_hash{'contacts'}{'overrides'}{$type}{'include'} = $includeloc{$type}.':'.&escape($includestr{$type}); + $newsetting{'override_'.$type}{'include'} = $contacts_hash{'contacts'}{'overrides'}{$type}{'include'}; + } + } + } + } if (keys(%currsetting) > 0) { foreach my $item (@contacts) { if ($to{$item} ne $currsetting{$item}) { @@ -9759,6 +11456,33 @@ sub modify_contacts { } } } + if (@statuses) { + if (ref($currsetting{'overrides'}) eq 'HASH') { + foreach my $key (keys(%{$currsetting{'overrides'}})) { + if (ref($currsetting{'overrides'}{$key}) eq 'HASH') { + if (ref($newsetting{'override_'.$key}) eq 'HASH') { + foreach my $item (@contacts,'bcc','others','include') { + if ($currsetting{'overrides'}{$key}{$item} ne $newsetting{'override_'.$key}{$item}) { + push(@{$changes{'overrides'}},$key); + last; + } + } + } else { + push(@{$changes{'overrides'}},$key); + } + } + } + foreach my $key (@overrides) { + unless (exists($currsetting{'overrides'}{$key})) { + push(@{$changes{'overrides'}},$key); + } + } + } else { + foreach my $key (@overrides) { + push(@{$changes{'overrides'}},$key); + } + } + } } else { my %default; $default{'supportemail'} = $Apache::lonnet::perlvar{'lonSupportEMail'}; @@ -9770,7 +11494,6 @@ sub modify_contacts { $default{'lonstatusmail'} = 'adminemail'; $default{'requestsmail'} = 'adminemail'; $default{'updatesmail'} = 'adminemail'; - $default{'hostipmail'} = 'adminemail'; foreach my $item (@contacts) { if ($to{$item} ne $default{$item}) { $changes{$item} = 1; @@ -9860,7 +11583,7 @@ sub modify_contacts { $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$bcc{$type}.'</span>'; } elsif (!@text) { $resulttext .= &mt('No one'); - } + } if ($includestr{$type} ne '') { if ($includeloc{$type} eq 'b') { $resulttext .= '<br />'.&mt('Text automatically added to e-mail body:').' '.$includestr{$type}; @@ -9874,6 +11597,60 @@ sub modify_contacts { $resulttext .= '</li>'; } } + if (ref($changes{'overrides'}) eq 'ARRAY') { + my @deletions; + foreach my $type (@{$changes{'overrides'}}) { + if ($usertypeshash{$type}) { + if (grep(/^\Q$type\E/,@overrides)) { + $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation set for [_1]", + $usertypeshash{$type}).'<ul><li>'; + if (ref($newsetting{'override_'.$type}) eq 'HASH') { + my @text; + foreach my $item (@contacts) { + if ($newsetting{'override_'.$type}{$item}) { + push(@text,$short_titles->{$item}); + } + } + if ($newsetting{'override_'.$type}{'others'} ne '') { + push(@text,$newsetting{'override_'.$type}{'others'}); + } + + if (@text) { + $resulttext .= &mt('Helpdesk e-mail sent to: [_1]', + '<span class="LC_cusr_emph">'.join(', ',@text).'</span>'); + } + if ($newsetting{'override_'.$type}{'bcc'} ne '') { + my $bcctext; + if (@text) { + $bcctext = ' '.&mt('with Bcc to'); + } else { + $bcctext = '(Bcc)'; + } + $resulttext .= $bcctext.': <span class="LC_cusr_emph">'.$newsetting{'override_'.$type}{'bcc'}.'</span>'; + } elsif (!@text) { + $resulttext .= &mt('Helpdesk e-mail sent to no one'); + } + $resulttext .= '</li>'; + if ($newsetting{'override_'.$type}{'include'} ne '') { + my ($loc,$str) = split(/:/,$newsetting{'override_'.$type}{'include'}); + if ($loc eq 'b') { + $resulttext .= '<li>'.&mt('Text automatically added to e-mail body:').' '.&unescape($str).'</li>'; + } elsif ($loc eq 's') { + $resulttext .= '<li>'.&mt('Text automatically added to e-mail subject:').' '.&unescape($str).'</li>'; + } + } + } + $resulttext .= '</li></ul></li>'; + } else { + push(@deletions,$usertypeshash{$type}); + } + } + } + if (@deletions) { + $resulttext .= '<li>'.&mt("Overrides based on requester's affiliation discontinued for: [_1]", + join(', ',@deletions)).'</li>'; + } + } my @offon = ('off','on'); if ($changes{'reporterrors'}) { $resulttext .= '<li>'. @@ -9929,7 +11706,6 @@ sub modify_contacts { &mt('Max size for file uploaded to help form by logged-in user set to [_1] MB.', $contacts_hash{'contacts'}{'helpform'}{'maxsize'}). '</li>'; - } } $resulttext .= '</ul>'; @@ -10242,7 +12018,6 @@ sub modify_selfcreation { # Populate $cancreate{'selfcreate'} array reference with types of user, for which self-creation of user accounts # is permitted. # - my ($emailrules,$emailruleorder) = &Apache::lonnet::inst_userrules($dom,'email'); my (@statuses,%email_rule); @@ -10292,7 +12067,7 @@ sub modify_selfcreation { if (($chosen eq 'inst') || ($chosen eq 'noninst')) { my $emaildom; if ($env{'form.cancreate_emaildomain_'.$chosen.'_'.$type} =~ /^\@[^\@]+$/) { - $emaildom = $env{'form.cancreate_emaildomain_'.$chosen.'_'.$type}; + $emaildom = $env{'form.cancreate_emaildomain_'.$chosen.'_'.$type}; $cancreate{'emaildomain'}{$type}{$chosen} = $emaildom; if (ref($curremaildom{$type}) eq 'HASH') { if (exists($curremaildom{$type}{$chosen})) { @@ -10304,7 +12079,7 @@ sub modify_selfcreation { } } elsif ($emaildom ne '') { push(@{$changes{'cancreate'}},'emaildomain'); - } + } } $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type}; } elsif ($chosen eq 'custom') { @@ -10731,7 +12506,7 @@ sub modify_selfcreation { ); if (@types) { if (@statuses) { - $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:'). + $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:'). '<ul>'; foreach my $status (@statuses) { if ($status eq 'default') { @@ -10757,7 +12532,7 @@ sub modify_selfcreation { $chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:'). '<ul>'; foreach my $status (@statuses) { - if ($status eq 'default') { + if ($type eq 'default') { $chgtext .= '<li>'.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>'; } else { $chgtext .= '<li>'.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'</li>'; @@ -10817,7 +12592,7 @@ sub modify_selfcreation { $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>'; } else { $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address needs to end: [_1]", - $cancreate{'emaildomain'}{$type}{'inst'}).'</li>'; + $cancreate{'emaildomain'}{$type}{'inst'}).'</li>'; } } } elsif ($cancreate{'emailoptions'}{$type} eq 'noninst') { @@ -10835,7 +12610,7 @@ sub modify_selfcreation { $output = '<li>'.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'</li>'; } else { $output = '<li>'.$usertypes{$type}.' -- '.&mt("User's e-mail address must not end: [_1]", - $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>'; + $cancreate{'emaildomain'}{$type}{'noninst'}).'</li>'; } } } @@ -10939,7 +12714,7 @@ sub modify_selfcreation { $typename = $othertitle; } else { $typename = $usertypes{$type}; - } + } $chgtext .= &mt('(Affiliation: [_1])',$typename); } if (@{$email_rule{$type}} > 0) { @@ -11297,12 +13072,10 @@ sub modify_defaults { my @allpos; my %alltypes; my @inststatusguest; - if (ref($currinststatus) eq 'HASH') { - if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') { - foreach my $type (@{$currinststatus->{'inststatusguest'}}) { - unless (grep(/^\Q$type\E$/,@todelete)) { - push(@inststatusguest,$type); - } + if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') { + foreach my $type (@{$currinststatus->{'inststatusguest'}}) { + unless (grep(/^\Q$type\E$/,@todelete)) { + push(@inststatusguest,$type); } } } @@ -11390,7 +13163,7 @@ sub modify_defaults { $resulttext =~ s/, $//; $resulttext .= '</li>'; } else { - $resulttext .= '<li>'.&mt('Institutional user status types deleted').'</li>'; + $resulttext .= '<li>'.&mt('Institutional user status types deleted').'</li>'; } } } else { @@ -11576,6 +13349,15 @@ sub modify_coursecategories { if ($domconfig{'coursecategories'}{'categorizecomm'} ne $env{'form.categorizecomm'}) { $changes{'categorizecomm'} = 1; $domconfig{'coursecategories'}{'categorizecomm'} = $env{'form.categorizecomm'}; + + } + if ($domconfig{'coursecategories'}{'togglecatsplace'} ne $env{'form.togglecatsplace'}) { + $changes{'togglecatsplace'} = 1; + $domconfig{'coursecategories'}{'togglecatsplace'} = $env{'form.togglecatsplace'}; + } + if ($domconfig{'coursecategories'}{'categorizeplace'} ne $env{'form.categorizeplace'}) { + $changes{'categorizeplace'} = 1; + $domconfig{'coursecategories'}{'categorizeplace'} = $env{'form.categorizeplace'}; } foreach my $item (@catitems) { if (grep(/^\Q$env{'form.coursecat_'.$item}\E$/,@cattypes)) { @@ -11590,11 +13372,15 @@ sub modify_coursecategories { $changes{'categorize'} = 1; $changes{'togglecatscomm'} = 1; $changes{'categorizecomm'} = 1; + $changes{'togglecatsplace'} = 1; + $changes{'categorizeplace'} = 1; $domconfig{'coursecategories'} = { togglecats => $env{'form.togglecats'}, categorize => $env{'form.categorize'}, togglecatscomm => $env{'form.togglecatscomm'}, categorizecomm => $env{'form.categorizecomm'}, + togglecatsplace => $env{'form.togglecatsplace'}, + categorizeplace => $env{'form.categorizeplace'}, }; foreach my $item (@catitems) { if ($env{'form.coursecat_'.$item} ne 'std') { @@ -11612,6 +13398,9 @@ sub modify_coursecategories { if (($domconfig{'coursecategories'}{'cats'}{'communities::0'} ne '') && ($env{'form.communities'} == 0)) { push(@deletecategory,'communities::0'); } + if (($domconfig{'coursecategories'}{'cats'}{'placement::0'} ne '') && ($env{'form.placement'} == 0)) { + push(@deletecategory,'placement::0'); + } } my (@predelcats,@predeltrails,%predelallitems,%sort_by_deltrail); if (ref($cathash) eq 'HASH') { @@ -11674,9 +13463,23 @@ sub modify_coursecategories { $adds{$newitem} = 1; } } + if ($env{'form.placement'} eq '1') { + if (ref($cathash) eq 'HASH') { + my $newitem = 'placement::0'; + if ($cathash->{$newitem} eq '') { + $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'}; + $adds{$newitem} = 1; + } + } else { + my $newitem = 'placement::0'; + $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.placement_pos'}; + $adds{$newitem} = 1; + } + } if ($env{'form.addcategory_name'} ne '') { if (($env{'form.addcategory_name'} ne 'instcode') && - ($env{'form.addcategory_name'} ne 'communities')) { + ($env{'form.addcategory_name'} ne 'communities') && + ($env{'form.addcategory_name'} ne 'placement')) { my $newitem = &escape($env{'form.addcategory_name'}).'::0'; $domconfig{'coursecategories'}{'cats'}{$newitem} = $env{'form.addcategory_pos'}; $adds{$newitem} = 1; @@ -11792,10 +13595,6 @@ sub modify_coursecategories { } $resulttext .= '</ul></li>'; } - &Apache::lonnet::do_cache_new('cats',$dom,$cathash,3600); - if (ref($lastactref) eq 'HASH') { - $lastactref->{'cats'} = 1; - } } $resulttext .= '</ul>'; if ($changes{'unauth'} || $changes{'auth'}) { @@ -12275,14 +14074,16 @@ sub modify_coursedefaults { my ($dom,$lastactref,%domconfig) = @_; my ($resulttext,$errors,%changes,%defaultshash); my %defaultchecked = ( + 'canuse_pdfforms' => 'off', 'uselcmath' => 'on', 'usejsme' => 'on' ); - my @toggles = ('uselcmath','usejsme'); + my @toggles = ('canuse_pdfforms','uselcmath','usejsme'); my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial', - 'uploadquota_community','uploadquota_textbook','mysqltables_official', - 'mysqltables_unofficial','mysqltables_community','mysqltables_textbook'); - my @types = ('official','unofficial','community','textbook'); + 'uploadquota_community','uploadquota_textbook','uploadquota_placement', + 'mysqltables_official','mysqltables_unofficial','mysqltables_community', + 'mysqltables_textbook','mysqltables_placement'); + my @types = ('official','unofficial','community','textbook','placement'); my %staticdefaults = ( anonsurvey_threshold => 10, uploadquota => 500, @@ -12340,6 +14141,7 @@ sub modify_coursedefaults { $defaultshash{'coursedefaults'}{$setting}{$type} = $newdef; } if ($currdef ne $newdef) { + my $staticdef; if ($item eq 'anonsurvey_threshold') { unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) { $changes{$item} = 1; @@ -12355,12 +14157,11 @@ sub modify_coursedefaults { my $texengine; if ($env{'form.texengine'} =~ /^(MathJax|mimetex|tth)$/) { $texengine = $env{'form.texengine'}; - my $currdef = $domconfig{'coursedefaults'}{'texengine'}; - if ($currdef eq '') { - unless ($texengine eq $Apache::lonnet::deftex) { + if ($defaultshash{'coursedefaults'}{'texengine'} eq '') { + unless ($texengine eq 'MathJax') { $changes{'texengine'} = 1; } - } elsif ($currdef ne $texengine) { + } elsif ($defaultshash{'coursedefaults'}{'texengine'} ne $texengine) { $changes{'texengine'} = 1; } } @@ -12485,10 +14286,10 @@ sub modify_coursedefaults { if ($putresult eq 'ok') { if (keys(%changes) > 0) { my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); - if (($changes{'uploadquota'}) || ($changes{'postsubmit'}) || + if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) || ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) || ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'})) { - foreach my $item ('uselcmath','usejsme','texengine') { + foreach my $item ('canuse_pdfforms','uselcmath','usejsme','texengine') { if ($changes{$item}) { $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item}; } @@ -12539,7 +14340,13 @@ sub modify_coursedefaults { } $resulttext = &mt('Changes made:').'<ul>'; foreach my $item (sort(keys(%changes))) { - if ($item eq 'uselcmath') { + if ($item eq 'canuse_pdfforms') { + if ($env{'form.'.$item} eq '1') { + $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>'; + } else { + $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>'; + } + } elsif ($item eq 'uselcmath') { if ($env{'form.'.$item} eq '1') { $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>'; } else { @@ -12564,7 +14371,7 @@ sub modify_coursedefaults { '<li>'.&mt('Official courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'official'}.'</b>').'</li>'. '<li>'.&mt('Unofficial courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'unofficial'}.'</b>').'</li>'. '<li>'.&mt('Textbook courses: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'textbook'}.'</b>').'</li>'. - + '<li>'.&mt('Placement tests: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'placement'}.'</b>').'</li>'. '<li>'.&mt('Communities: [_1] MB','<b>'.$defaultshash{'coursedefaults'}{'uploadquota'}{'community'}.'</b>').'</li>'. '</ul>'. '</li>'; @@ -12577,6 +14384,7 @@ sub modify_coursedefaults { '<li>'.&mt('Official courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'official'}.'</b>').'</li>'. '<li>'.&mt('Unofficial courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'unofficial'}.'</b>').'</li>'. '<li>'.&mt('Textbook courses: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'textbook'}.'</b>').'</li>'. + '<li>'.&mt('Placement tests: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'placement'}.'</b>').'</li>'. '<li>'.&mt('Communities: [_1] s','<b>'.$defaultshash{'coursedefaults'}{'mysqltables'}{'community'}.'</b>').'</li>'. '</ul>'. '</li>'; @@ -12612,6 +14420,8 @@ sub modify_coursedefaults { $resulttext .= &mt('Unofficial courses'); } elsif ($type eq 'textbook') { $resulttext .= &mt('Textbook courses'); + } elsif ($type eq 'placement') { + $resulttext .= &mt('Placement tests'); } $resulttext .= ' -- '.$display.'</li>'; } @@ -12663,7 +14473,7 @@ sub modify_coursedefaults { sub modify_selfenrollment { my ($dom,$lastactref,%domconfig) = @_; my ($resulttext,$errors,%changes,%selfenrollhash,%ordered); - my @types = ('official','unofficial','community','textbook'); + my @types = ('official','unofficial','community','textbook','placement'); my %titles = &tool_titles(); my %descs = &Apache::lonuserutils::selfenroll_default_descs(); ($ordered{'admin'},my $titlesref) = &Apache::lonuserutils::get_selfenroll_titles(); @@ -12910,8 +14720,8 @@ sub modify_usersessions { ); my @prefixes = ('remote','hosted','spares'); my @lcversions = &Apache::lonnet::all_loncaparevs(); - my (%by_ip,%by_location,@intdoms); - &build_location_hashes(\@intdoms,\%by_ip,\%by_location); + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); my @locations = sort(keys(%by_location)); my (%defaultshash,%changes); foreach my $prefix (@prefixes) { @@ -13227,6 +15037,298 @@ sub modify_usersessions { return $resulttext; } +sub modify_ssl { + my ($dom,$lastactref,%domconfig) = @_; + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); + my @locations = sort(keys(%by_location)); + my %servers = &Apache::lonnet::internet_dom_servers($dom); + my (%defaultshash,%changes); + my $action = 'ssl'; + my @prefixes = ('connto','connfrom','replication'); + foreach my $prefix (@prefixes) { + $defaultshash{$action}{$prefix} = {}; + } + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); + my $resulttext; + my %iphost = &Apache::lonnet::get_iphost(); + my @reptypes = ('certreq','nocertreq'); + my @connecttypes = ('dom','intdom','other'); + my %types = ( + connto => \@connecttypes, + connfrom => \@connecttypes, + replication => \@reptypes, + ); + foreach my $prefix (sort(keys(%types))) { + foreach my $type (@{$types{$prefix}}) { + if (($prefix eq 'connto') || ($prefix eq 'connfrom')) { + my $value = 'yes'; + if ($env{'form.'.$prefix.'_'.$type} =~ /^(no|req)$/) { + $value = $env{'form.'.$prefix.'_'.$type}; + } + if (ref($domconfig{$action}{$prefix}) eq 'HASH') { + if ($domconfig{$action}{$prefix}{$type} ne '') { + if ($value ne $domconfig{$action}{$prefix}{$type}) { + $changes{$prefix}{$type} = 1; + } + $defaultshash{$action}{$prefix}{$type} = $value; + } else { + $defaultshash{$action}{$prefix}{$type} = $value; + $changes{$prefix}{$type} = 1; + } + } else { + $defaultshash{$action}{$prefix}{$type} = $value; + $changes{$prefix}{$type} = 1; + } + if (($type eq 'dom') && (keys(%servers) == 1)) { + delete($changes{$prefix}{$type}); + } elsif (($type eq 'intdom') && (@instdoms == 1)) { + delete($changes{$prefix}{$type}); + } elsif (($type eq 'other') && (keys(%by_location) == 0)) { + delete($changes{$prefix}{$type}); + } + } elsif ($prefix eq 'replication') { + if (@locations > 0) { + my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'}; + my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type); + my @okvals; + foreach my $val (@vals) { + if ($val =~ /:/) { + my @items = split(/:/,$val); + foreach my $item (@items) { + if (ref($by_location{$item}) eq 'ARRAY') { + push(@okvals,$item); + } + } + } else { + if (ref($by_location{$val}) eq 'ARRAY') { + push(@okvals,$val); + } + } + } + @okvals = sort(@okvals); + if (ref($domconfig{$action}) eq 'HASH') { + if (ref($domconfig{$action}{$prefix}) eq 'HASH') { + if (ref($domconfig{$action}{$prefix}{$type}) eq 'ARRAY') { + if ($inuse == 0) { + $changes{$prefix}{$type} = 1; + } else { + $defaultshash{$action}{$prefix}{$type} = \@okvals; + my @changed = &Apache::loncommon::compare_arrays($domconfig{$action}{$prefix}{$type},$defaultshash{$action}{$prefix}{$type}); + if (@changed > 0) { + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{$action}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{$action}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{$action}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } + } + } + } + my $nochgmsg = &mt('No changes made to LON-CAPA SSL settings'); + if (keys(%changes) > 0) { + my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, + $dom); + if ($putresult eq 'ok') { + if (ref($defaultshash{$action}) eq 'HASH') { + if (ref($defaultshash{$action}{'replication'}) eq 'HASH') { + $domdefaults{'replication'} = $defaultshash{$action}{'replication'}; + } + if (ref($defaultshash{$action}{'connto'}) eq 'HASH') { + $domdefaults{'connto'} = $domconfig{$action}{'connto'}; + } + if (ref($defaultshash{$action}{'connfrom'}) eq 'HASH') { + $domdefaults{'connfrom'} = $domconfig{$action}{'connfrom'}; + } + } + my $cachetime = 24*60*60; + &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } + if (keys(%changes) > 0) { + my %titles = &ssl_titles(); + $resulttext = &mt('Changes made:').'<ul>'; + foreach my $prefix (@prefixes) { + if (ref($changes{$prefix}) eq 'HASH') { + $resulttext .= '<li>'.$titles{$prefix}.'<ul>'; + foreach my $type (@{$types{$prefix}}) { + if (defined($changes{$prefix}{$type})) { + my $newvalue; + if (ref($defaultshash{$action}) eq 'HASH') { + if (ref($defaultshash{$action}{$prefix})) { + if (($prefix eq 'connto') || ($prefix eq 'connfrom')) { + $newvalue = $titles{$defaultshash{$action}{$prefix}{$type}}; + } elsif (ref($defaultshash{$action}{$prefix}{$type}) eq 'ARRAY') { + if (@{$defaultshash{$action}{$prefix}{$type}} > 0) { + $newvalue = join(', ',@{$defaultshash{$action}{$prefix}{$type}}); + } + } + } + if ($newvalue eq '') { + $resulttext .= '<li>'.&mt('[_1] set to: none',$titles{$type}).'</li>'; + } else { + $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$titles{$type},$newvalue).'</li>'; + } + } + } + } + $resulttext .= '</ul>'; + } + } + } else { + $resulttext = $nochgmsg; + } + } else { + $resulttext = '<span class="LC_error">'. + &mt('An error occurred: [_1]',$putresult).'</span>'; + } + } else { + $resulttext = $nochgmsg; + } + return $resulttext; +} + +sub modify_trust { + my ($dom,$lastactref,%domconfig) = @_; + my (%by_ip,%by_location,@intdoms,@instdoms); + &build_location_hashes(\@intdoms,\%by_ip,\%by_location,\@instdoms); + my @locations = sort(keys(%by_location)); + my @prefixes = qw(content shared enroll othcoau coaurem domroles catalog reqcrs msg); + my @types = ('exc','inc'); + my (%defaultshash,%changes); + foreach my $prefix (@prefixes) { + $defaultshash{'trust'}{$prefix} = {}; + } + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); + my $resulttext; + foreach my $prefix (@prefixes) { + foreach my $type (@types) { + my $inuse = $env{'form.'.$prefix.'_'.$type.'_inuse'}; + my @vals = &Apache::loncommon::get_env_multiple('form.'.$prefix.'_'.$type); + my @okvals; + foreach my $val (@vals) { + if ($val =~ /:/) { + my @items = split(/:/,$val); + foreach my $item (@items) { + if (ref($by_location{$item}) eq 'ARRAY') { + push(@okvals,$item); + } + } + } else { + if (ref($by_location{$val}) eq 'ARRAY') { + push(@okvals,$val); + } + } + } + @okvals = sort(@okvals); + if (ref($domconfig{'trust'}) eq 'HASH') { + if (ref($domconfig{'trust'}{$prefix}) eq 'HASH') { + if (ref($domconfig{'trust'}{$prefix}{$type}) eq 'ARRAY') { + if ($inuse == 0) { + $changes{$prefix}{$type} = 1; + } else { + $defaultshash{'trust'}{$prefix}{$type} = \@okvals; + my @changed = &Apache::loncommon::compare_arrays($domconfig{'trust'}{$prefix}{$type},$defaultshash{'trust'}{$prefix}{$type}); + if (@changed > 0) { + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{'trust'}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{'trust'}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } else { + if ($inuse == 1) { + $defaultshash{'trust'}{$prefix}{$type} = \@okvals; + $changes{$prefix}{$type} = 1; + } + } + } + } + my $nochgmsg = &mt('No changes made to trust settings.'); + if (keys(%changes) > 0) { + my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash, + $dom); + if ($putresult eq 'ok') { + if (ref($defaultshash{'trust'}) eq 'HASH') { + foreach my $prefix (@prefixes) { + if (ref($defaultshash{'trust'}{$prefix}) eq 'HASH') { + $domdefaults{'trust'.$prefix} = $defaultshash{'trust'}{$prefix}; + } + } + } + my $cachetime = 24*60*60; + &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } + if (keys(%changes) > 0) { + my %lt = &trust_titles(); + $resulttext = &mt('Changes made:').'<ul>'; + foreach my $prefix (@prefixes) { + if (ref($changes{$prefix}) eq 'HASH') { + $resulttext .= '<li>'.$lt{$prefix}.'<ul>'; + foreach my $type (@types) { + if (defined($changes{$prefix}{$type})) { + my $newvalue; + if (ref($defaultshash{'trust'}) eq 'HASH') { + if (ref($defaultshash{'trust'}{$prefix})) { + if (ref($defaultshash{'trust'}{$prefix}{$type}) eq 'ARRAY') { + if (@{$defaultshash{'trust'}{$prefix}{$type}} > 0) { + $newvalue = join(', ',@{$defaultshash{'trust'}{$prefix}{$type}}); + } + } + } + } + if ($newvalue eq '') { + $resulttext .= '<li>'.&mt('[_1] set to: none',$lt{$type}).'</li>'; + } else { + $resulttext .= '<li>'.&mt('[_1] set to: [_2].',$lt{$type},$newvalue).'</li>'; + } + } + } + $resulttext .= '</ul>'; + } + } + $resulttext .= '</ul>'; + } else { + $resulttext = $nochgmsg; + } + } else { + $resulttext = '<span class="LC_error">'. + &mt('An error occurred: [_1]',$putresult).'</span>'; + } + } else { + $resulttext = $nochgmsg; + } + return $resulttext; +} + sub modify_loadbalancing { my ($dom,%domconfig) = @_; my $primary_id = &Apache::lonnet::domain($dom,'primary'); @@ -14224,7 +16326,7 @@ sub devalidate_remote_domconfs { my %servers = &Apache::lonnet::internet_dom_servers($dom); my %thismachine; map { $thismachine{$_} = 1; } &Apache::lonnet::current_machine_ids(); - my @posscached = ('domainconfig','domdefaults','usersessions','directorysrch','cats'); + my @posscached = ('domainconfig','domdefaults','ltitools','usersessions','directorysrch'); if (keys(%servers)) { foreach my $server (keys(%servers)) { next if ($thismachine{$server});