--- loncom/interface/domainprefs.pm 2016/08/07 00:28:39 1.160.6.68 +++ loncom/interface/domainprefs.pm 2016/10/24 22:37:24 1.160.6.74 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.160.6.68 2016/08/07 00:28:39 raeburn Exp $ +# $Id: domainprefs.pm,v 1.160.6.74 2016/10/24 22:37:24 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -213,15 +213,15 @@ sub handler { 'quotas','autoenroll','autoupdate','autocreate', 'directorysrch','usercreation','usermodification', 'contacts','defaults','scantron','coursecategories', - 'serverstatuses','requestcourses','coursedefaults', - 'usersessions','loadbalancing','requestauthor', - 'selfenrollment','inststatus'],$dom); + 'serverstatuses','requestcourses','helpsettings', + 'coursedefaults','usersessions','loadbalancing', + 'requestauthor','selfenrollment','inststatus'],$dom); my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll', 'autoupdate','autocreate','directorysrch','contacts', 'usercreation','selfcreation','usermodification','scantron', 'requestcourses','requestauthor','coursecategories', - 'serverstatuses','coursedefaults','selfenrollment', - 'usersessions'); + 'serverstatuses','helpsettings','coursedefaults', + 'selfenrollment','usersessions'); my %existing; if (ref($domconfig{'loadbalancing'}) eq 'HASH') { %existing = %{$domconfig{'loadbalancing'}}; @@ -304,9 +304,11 @@ sub handler { modify => \&modify_autocreate, }, 'directorysrch' => - { text => 'Institutional directory searches', + { text => 'Directory searches', help => 'Domain_Configuration_InstDirectory_Search', - header => [{col1 => 'Setting', + header => [{col1 => 'Institutional Directory Setting', + col2 => 'Value',}, + {col1 => 'LON-CAPA Directory Setting', col2 => 'Value',}], print => \&print_directorysrch, modify => \&modify_directorysrch, @@ -411,6 +413,16 @@ sub handler { print => \&print_serverstatuses, modify => \&modify_serverstatuses, }, + 'helpsettings' => + {text => 'Support settings', + help => 'Domain_Configuration_Help_Settings', + header => [{col1 => 'Help Page Settings (logged-in users)', + col2 => 'Value'}, + {col1 => 'Helpdesk Roles', + col2 => 'Settings'},], + print => \&print_helpsettings, + modify => \&modify_helpsettings, + }, 'coursedefaults' => {text => 'Course/Community defaults', help => 'Domain_Configuration_Course_Defaults', @@ -619,6 +631,8 @@ sub process_changes { $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); } elsif ($action eq 'requestauthor') { $output = &modify_quotas($r,$dom,$action,$lastactref,%domconfig); + } elsif ($action eq 'helpsettings') { + $output = &modify_helpsettings($r,$dom,$confname,%domconfig); } elsif ($action eq 'coursedefaults') { $output = &modify_coursedefaults($dom,$lastactref,%domconfig); } elsif ($action eq 'selfenrollment') { @@ -639,6 +653,22 @@ sub print_config_box { $output = &coursecategories_javascript($settings); } elsif ($action eq 'defaults') { $output = &defaults_javascript($settings); + } elsif ($action eq 'helpsettings') { + my (%privs,%levelscurrent); + my %full=(); + my %levels=( + course => {}, + domain => {}, + system => {}, + ); + my $context = 'domain'; + my $crstype = 'Course'; + my $formname = 'display'; + &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent); + my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); + $output = + &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname,\%full, + \@templateroles); } $output .= ' @@ -656,6 +686,7 @@ sub print_config_box { my $colspan = ''; my $rightcolspan = ''; if (($action eq 'rolecolors') || ($action eq 'defaults') || + ($action eq 'directorysrch') || (($action eq 'login') && ($numheaders < 4))) { $colspan = ' colspan="2"'; } @@ -673,7 +704,8 @@ 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 'selfenrollment') || ($action eq 'usersessions') || ($action eq 'directorysrch') || + ($action eq 'helpsettings')) { $output .= $item->{'print'}->('top',$dom,$settings,\$rowtotal); } elsif ($action eq 'coursecategories') { $output .= $item->{'print'}->('top',$dom,$item,$settings,\$rowtotal); @@ -728,7 +760,8 @@ sub print_config_box { } $rowtotal ++; } elsif (($action eq 'usermodification') || ($action eq 'coursedefaults') || - ($action eq 'defaults')) { + ($action eq 'defaults') || ($action eq 'directorysrch') || + ($action eq 'helpsettings')) { $output .= $item->{'print'}->('bottom',$dom,$settings,\$rowtotal); } elsif ($action eq 'login') { if ($numheaders == 4) { @@ -841,7 +874,7 @@ sub print_config_box { '. + ''."\n"; + $itemcount ++; + } $$rowtotal += $itemcount; return $datatable; @@ -4542,7 +4707,8 @@ sub email_as_username { sub captcha_choice { my ($context,$settings,$itemcount) = @_; - my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext); + my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext, + $vertext,$currver); my %lt = &captcha_phrases(); $keyentry = 'hidden'; if ($context eq 'cancreate') { @@ -4560,6 +4726,11 @@ sub captcha_choice { $pubtext = $lt{'pub'}; $privtext = $lt{'priv'}; $keyentry = 'text'; + $vertext = $lt{'ver'}; + $currver = $settings->{'recaptchaversion'}; + if ($currver ne '2') { + $currver = 1; + } } if (ref($settings->{'recaptchakeys'}) eq 'HASH') { $currpub = $settings->{'recaptchakeys'}{'public'}; @@ -4593,7 +4764,11 @@ sub captcha_choice { $currpub.'" size="40" />
'."\n". ''.$privtext.' '."\n". '
'; - if (($action eq 'login') || ($action eq 'directorysrch')) { + if ($action eq 'login') { $output .= ' '; } elsif ($action eq 'serverstatuses') { @@ -885,13 +918,12 @@ sub print_config_box { $rowtotal ++; if ($action eq 'quotas') { $output .= &print_quotas($dom,$settings,\$rowtotal,$action); - } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || ($action eq 'directorysrch') || - ($action eq 'contacts') || ($action eq 'serverstatuses') || ($action eq 'loadbalancing')) { + } elsif (($action eq 'autoenroll') || ($action eq 'autocreate') || + ($action eq 'contacts') || ($action eq 'serverstatuses') || + ($action eq 'loadbalancing')) { $output .= $item->{'print'}->($dom,$settings,\$rowtotal); } elsif ($action eq 'scantron') { $output .= &print_scantronformat($r,$dom,$confname,$settings,\$rowtotal); - } elsif ($action eq 'helpsettings') { - $output .= &print_helpsettings($dom,$confname,$settings,\$rowtotal); } } $output .= ' @@ -2604,115 +2636,149 @@ sub print_autocreate { } sub print_directorysrch { - my ($dom,$settings,$rowtotal) = @_; - my $srchon = ' '; - my $srchoff = ' checked="checked" '; - my ($exacton,$containson,$beginson); - my $localon = ' '; - my $localoff = ' checked="checked" '; - if (ref($settings) eq 'HASH') { - if ($settings->{'available'} eq '1') { - $srchon = $srchoff; - $srchoff = ' '; - } - if ($settings->{'localonly'} eq '1') { - $localon = $localoff; - $localoff = ' '; - } - if (ref($settings->{'searchtypes'}) eq 'ARRAY') { - foreach my $type (@{$settings->{'searchtypes'}}) { - if ($type eq 'exact') { + my ($position,$dom,$settings,$rowtotal) = @_; + my $datatable; + if ($position eq 'top') { + my $instsrchon = ' '; + my $instsrchoff = ' checked="checked" '; + my ($exacton,$containson,$beginson); + my $instlocalon = ' '; + my $instlocaloff = ' checked="checked" '; + if (ref($settings) eq 'HASH') { + if ($settings->{'available'} eq '1') { + $instsrchon = $instsrchoff; + $instsrchoff = ' '; + } + if ($settings->{'localonly'} eq '1') { + $instlocalon = $instlocaloff; + $instlocaloff = ' '; + } + if (ref($settings->{'searchtypes'}) eq 'ARRAY') { + foreach my $type (@{$settings->{'searchtypes'}}) { + if ($type eq 'exact') { + $exacton = ' checked="checked" '; + } elsif ($type eq 'contains') { + $containson = ' checked="checked" '; + } elsif ($type eq 'begins') { + $beginson = ' checked="checked" '; + } + } + } else { + if ($settings->{'searchtypes'} eq 'exact') { + $exacton = ' checked="checked" '; + } elsif ($settings->{'searchtypes'} eq 'contains') { + $containson = ' checked="checked" '; + } elsif ($settings->{'searchtypes'} eq 'specify') { $exacton = ' checked="checked" '; - } elsif ($type eq 'contains') { $containson = ' checked="checked" '; - } elsif ($type eq 'begins') { - $beginson = ' checked="checked" '; } } - } else { - if ($settings->{'searchtypes'} eq 'exact') { - $exacton = ' checked="checked" '; - } elsif ($settings->{'searchtypes'} eq 'contains') { - $containson = ' checked="checked" '; - } elsif ($settings->{'searchtypes'} eq 'specify') { - $exacton = ' checked="checked" '; - $containson = ' checked="checked" '; - } } - } - my ($searchtitles,$titleorder) = &sorted_searchtitles(); - my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + my ($searchtitles,$titleorder) = &sorted_searchtitles(); + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - my $numinrow = 4; - my $cansrchrow = 0; - my $datatable=''. - ''. - ''. - ''. - ''. - ''. - ''; - $$rowtotal += 2; - if (ref($usertypes) eq 'HASH') { - if (keys(%{$usertypes}) > 0) { - $datatable .= &insttypes_row($settings,$types,$usertypes,$dom, - $numinrow,$othertitle,'cansearch'); - $cansrchrow = 1; + my $numinrow = 4; + my $cansrchrow = 0; + $datatable=''. + ''. + ''. + ''. + ''. + ''. + ''; + $$rowtotal += 2; + if (ref($usertypes) eq 'HASH') { + if (keys(%{$usertypes}) > 0) { + $datatable .= &insttypes_row($settings,$types,$usertypes,$dom, + $numinrow,$othertitle,'cansearch'); + $cansrchrow = 1; + } } - } - if ($cansrchrow) { - $$rowtotal ++; - $datatable .= ''; - } else { - $datatable .= ''; - } - $datatable .= ''; + $$rowtotal ++; + if ($cansrchrow) { + $datatable .= ''; + } else { + $datatable .= ''; + } + $datatable .= ''. + ''; + $$rowtotal ++; } else { - $datatable .= ''; + my $domsrchon = ' checked="checked" '; + my $domsrchoff = ' '; + my $domlocalon = ' '; + my $domlocaloff = ' checked="checked" '; + if (ref($settings) eq 'HASH') { + if ($settings->{'lclocalonly'} eq '1') { + $domlocalon = $domlocaloff; + $domlocaloff = ' '; + } + if ($settings->{'lcavailable'} eq '0') { + $domsrchoff = $domsrchon; + $domsrchon = ' '; + } + } + $datatable=''. + ''. + ''. + ''. + ''. + ''. + ''; + $$rowtotal += 2; } - $datatable .= ''. - ''; - $$rowtotal ++; return $datatable; } @@ -2816,18 +2882,92 @@ sub print_contacts { } sub print_helpsettings { - my ($dom,$confname,$settings,$rowtotal) = @_; + my ($position,$dom,$settings,$rowtotal) = @_; + my $confname = $dom.'-domainconfig'; my ($datatable,$itemcount); - $itemcount = 1; - my (%choices,%defaultchecked,@toggles); - $choices{'submitbugs'} = &mt('Display link to: [_1]?', - &Apache::loncommon::modal_link('http://bugs.loncapa.org', - &mt('LON-CAPA bug tracker'),600,500)); - %defaultchecked = ('submitbugs' => 'on'); - @toggles = ('submitbugs',); - - ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, - \%choices,$itemcount); + if ($position eq 'top') { + $itemcount = 1; + my (%choices,%defaultchecked,@toggles); + $choices{'submitbugs'} = &mt('Display link to: [_1]?', + &Apache::loncommon::modal_link('http://bugs.loncapa.org', + &mt('LON-CAPA bug tracker'),600,500)); + %defaultchecked = ('submitbugs' => 'on'); + @toggles = ('submitbugs'); + ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, + \%choices,$itemcount); + $$rowtotal ++; + } else { + my $css_class; + my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_'); + my %customroles; + foreach my $key (keys(%existing)) { + if ($key=~/^rolesdef\_(\w+)$/) { + my $rolename = $1; + my %privs; + ($privs{'system'},$privs{'domain'},$privs{'course'}) = split(/\_/,$existing{$key}); + $customroles{$rolename} = \%privs; + } + } + my $count = 0; + my $context = 'domprefs'; + my $crstype = 'Course'; + foreach my $role (sort(keys(%customroles))) { + my $prefix = 'custhelp'.$count; + my %full=(); + my %levels= ( + course => {}, + domain => {}, + system => {}, + ); + my %levelscurrent=( + course => {}, + domain => {}, + system => {}, + ); + &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent); + my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); + $css_class = $itemcount%2?' class="LC_odd_row"':''; + $datatable .= ''. + ''; + $count ++; + $itemcount ++; + } + $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $newcust = 'custhelp'.$count; + my (%privs,%levelscurrent); + my %full=(); + my %levels= ( + course => {}, + domain => {}, + system => {}, + ); + &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent); + my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); + $datatable .= ''. + ''; + $count ++; + $$rowtotal += $count; + } return $datatable; } @@ -2899,11 +3039,13 @@ sub print_coursedefaults { usejsme => 'Molecule editor uses JSME (HTML5) in place of JME (Java)', postsubmit => 'Disable submit button/keypress following student submission', canclone => "People who may clone a course (besides course's owner and coordinators)", + mysqltables => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver', ); my %staticdefaults = ( anonsurvey_threshold => 10, uploadquota => 500, postsubmit => 60, + mysqltables => 172800, ); if ($position eq 'top') { %defaultchecked = ( @@ -2987,7 +3129,7 @@ sub print_coursedefaults { $itemcount ++; } else { $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; - my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout); + my ($currdefresponder,%defcredits,%curruploadquota,%deftimeout,%currmysql); my $currusecredits = 0; my $postsubmitclient = 1; my @types = ('official','unofficial','community','textbook'); @@ -3031,6 +3173,15 @@ sub print_coursedefaults { $deftimeout{$type} = $staticdefaults{'postsubmit'}; } } + if (ref($settings->{'mysqltables'}) eq 'HASH') { + foreach my $type (keys(%{$settings->{'mysqltables'}})) { + $currmysql{$type} = $settings->{'mysqltables'}{$type}; + } + } else { + foreach my $type (@types) { + $currmysql{$type} = $staticdefaults{'mysqltables'}; + } + } } else { foreach my $type (@types) { $deftimeout{$type} = $staticdefaults{'postsubmit'}; @@ -3108,13 +3259,27 @@ sub print_coursedefaults { $additional .= '
'.&mt($item->{'header'}->[0]->{'col1'}).'
'.&mt('Directory search available?').' '. - '
'.&mt('Other domains can search?').' '. - '
'.&mt('Institutional directory search available?').' '. + '
'.&mt('Other domains can search institution?').' '. + '
'.&mt('Supported search methods'). - ''; - foreach my $title (@{$titleorder}) { - if (defined($searchtitles->{$title})) { - my $check = ' '; - if (ref($settings) eq 'HASH') { - if (ref($settings->{'searchby'}) eq 'ARRAY') { - if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) { - $check = ' checked="checked" '; + if ($cansrchrow) { + $$rowtotal ++; + $datatable .= ''; + } else { + $datatable .= ''; + } + $datatable .= ''; - $$rowtotal ++; - if ($cansrchrow) { - $datatable .= ''; + $datatable .= '
'.&mt('Supported search methods'). + ''; + foreach my $title (@{$titleorder}) { + if (defined($searchtitles->{$title})) { + my $check = ' '; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'searchby'}) eq 'ARRAY') { + if (grep(/^\Q$title\E$/,@{$settings->{'searchby'}})) { + $check = ' checked="checked" '; + } } } + $datatable .= ''; } - $datatable .= ''; } - } - $datatable .= '
'. + ''. - '
'.&mt('Search latitude').''. + ' '. + ' '. + '
'.&mt('LON-CAPA directory search available?').' '. + '
'.&mt('Other domains can search LON-CAPA domain?').' '. + '
'.&mt('Search latitude').''. - ' '. - ' '. - '
'.&mt('Existing helpdesk role:').' '. + ''.$role.'
'. + &Apache::lonuserutils::custom_role_header($context,$crstype, + \@templateroles,$prefix). + &Apache::lonuserutils::custom_role_table($crstype,\%full,\%levels, + \%levelscurrent,$prefix). + '
'. + ''.&mt('Name of new helpdesk role:').' '. + ''. + '
'. + &Apache::lonuserutils::custom_role_header($context,$crstype, + \@templateroles,$newcust). + &Apache::lonuserutils::custom_role_table('Course',\%full,\%levels, + \%levelscurrent,$newcust). + '

'. + '
'."\n"; %defaultchecked = ('postsubmit' => 'on'); @toggles = ('postsubmit'); - my $current = { - 'postsubmit' => $postsubmitclient, - }; + $current = { + 'postsubmit' => $postsubmitclient, + }; ($table,$itemcount) = &radiobutton_prefs($current,\@toggles,\%defaultchecked, \%choices,$itemcount,$onclick,$additional,'left'); $datatable .= $table; + $css_class = $itemcount%2 ? ' class="LC_odd_row"' : ''; + $datatable .= '
'. + $choices{'mysqltables'}. + ''. + ''; + foreach my $type (@types) { + $datatable .= ''; + } + $datatable .= '
'.&mt($type).'
'. + '
'."\n". + $currpriv.'" size="40" />
'. + ''.$vertext.' '."\n". + '
'. + ''."\n". ''; return $output; } @@ -6154,7 +6329,7 @@ sub modify_login { if ($domservers{$lonhost}) { if (ref($domconfig{'login'}{'headtag'}{$lonhost}) eq 'HASH') { $currheadtagurls{$lonhost} = $domconfig{'login'}{'headtag'}{$lonhost}{'url'}; - $currexempt{$lonhost} = $domconfig{'login'}{'headtag'}{$lonhost}{'exempt'} + $currexempt{$lonhost} = $domconfig{'login'}{'headtag'}{$lonhost}{'exempt'}; } } } @@ -6380,6 +6555,13 @@ sub modify_login { $chgtxt .= ''; $resulttext .= '
  • '.$chgtxt.'
  • '; } + } elsif ($item eq 'recaptchaversion') { + if (ref($loginhash{'login'}) eq 'HASH') { + if ($loginhash{'login'}{'captcha'} eq 'recaptcha') { + $resulttext .= '
  • '.&mt('ReCAPTCHA for helpdesk form set to version [_1]',$loginhash{'login'}{'recaptchaversion'}). + '
  • '; + } + } } else { $resulttext .= '
  • '.&mt("$title{$item} set to $offon[$env{'form.'.$item}]").'
  • '; } @@ -8254,8 +8436,10 @@ sub modify_directorysrch { $currdirsrch{$key} = $domconfig{'directorysrch'}{$key}; } } - my %title = ( available => 'Directory search available', - localonly => 'Other domains can search', + my %title = ( available => 'Institutional directory search available', + localonly => 'Other domains can search institution', + lcavailable => 'LON-CAPA directory search available', + lclocalonly => 'Other domains can search LON-CAPA domain', searchby => 'Search types', searchtypes => 'Search latitude'); my @offon = ('off','on'); @@ -8329,7 +8513,9 @@ sub modify_directorysrch { my %dirsrch_hash = ( directorysrch => { available => $env{'form.dirsrch_available'}, cansearch => \@cansearch, - localonly => $env{'form.dirsrch_localonly'}, + localonly => $env{'form.dirsrch_instlocalonly'}, + lclocalonly => $env{'form.dirsrch_domlocalonly'}, + lcavailable => $env{'form.dirsrch_domavailable'}, searchby => \@searchby, searchtypes => \@searchtypes, } @@ -8346,24 +8532,47 @@ sub modify_directorysrch { $changes{'available'} = 1; } } - if (exists($currdirsrch{'localonly'})) { - if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_localonly'}) { - $changes{'localonly'} = 1; + if (exists($currdirsrch{'lcavailable'})) { + if ($currdirsrch{'lcavailable'} ne $env{'form.dirsrch_domavailable'}) { + $changes{'lcavailable'} = 1; } } else { - if ($env{'form.dirsrch_localonly'} eq '1') { + if ($env{'form.dirsrch_lcavailable'} eq '1') { + $changes{'lcavailable'} = 1; + } + } + if (exists($currdirsrch{'localonly'})) { + if ($currdirsrch{'localonly'} ne $env{'form.dirsrch_instlocalonly'}) { $changes{'localonly'} = 1; } + } else { + if ($env{'form.dirsrch_instlocalonly'} eq '1') { + $changes{'localonly'} = 1; + } + } + if (exists($currdirsrch{'lclocalonly'})) { + if ($currdirsrch{'lclocalonly'} ne $env{'form.dirsrch_domlocalonly'}) { + $changes{'lclocalonly'} = 1; + } + } else { + if ($env{'form.dirsrch_domlocalonly'} eq '1') { + $changes{'lclocalonly'} = 1; + } } if (keys(%changes) > 0) { $resulttext = &mt('Changes made:').''; } else { - $resulttext = &mt('No changes made to institution directory search settings'); + $resulttext = &mt('No changes made to directory search settings'); } } else { $resulttext = ''. @@ -8601,7 +8810,8 @@ sub modify_usercreation { if (ref($domconfig{'usercreation'}{$key}) eq 'HASH') { foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) { if (($item eq 'selfcreate') || ($item eq 'statustocreate') || - ($item eq 'captcha') || ($item eq 'recaptchakeys')) { + ($item eq 'captcha') || ($item eq 'recaptchakeys') || + ($item eq 'recaptchaversion')) { $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item}; } else { $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item}; @@ -8825,6 +9035,7 @@ sub modify_selfcreation { foreach my $item (keys(%{$domconfig{'usercreation'}{$key}})) { if (($item eq 'selfcreate') || ($item eq 'statustocreate') || ($item eq 'captcha') || ($item eq 'recaptchakeys') || + ($item eq 'recaptchaversion') || ($item eq 'emailusername') || ($item eq 'notify') || ($item eq 'selfcreateprocessing') || ($item eq 'shibenv')) { $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item}; @@ -9154,6 +9365,7 @@ sub modify_selfcreation { # $save_usercreate{'cancreate'}{'captcha'} = $savecaptcha{'captcha'}; $save_usercreate{'cancreate'}{'recaptchakeys'} = $savecaptcha{'recaptchakeys'}; + $save_usercreate{'cancreate'}{'recaptchaversion'} = $savecaptcha{'recaptchaversion'}; $save_usercreate{'cancreate'}{'selfcreate'} = $cancreate{'selfcreate'}; if (ref($cancreate{'notify'}) eq 'HASH') { $save_usercreate{'cancreate'}{'notify'} = $cancreate{'notify'}; @@ -9315,6 +9527,10 @@ sub modify_selfcreation { $chgtext .= '
  • '.&mt('Private key set to [_1]',$pubkey).'
  • '; } $chgtext .= ''; + } elsif ($type eq 'recaptchaversion') { + if ($savecaptcha{'captcha'} eq 'recaptcha') { + $chgtext .= &mt('ReCAPTCHA set to version [_1]',$savecaptcha{$type}); + } } elsif ($type eq 'emailusername') { if (ref($cancreate{'emailusername'}) eq 'HASH') { if (ref($types) eq 'ARRAY') { @@ -9435,7 +9651,7 @@ sub process_captcha { $changes->{'captcha'} = 1; } } - my ($newpub,$newpriv,$currpub,$currpriv); + my ($newpub,$newpriv,$currpub,$currpriv,$newversion,$currversion); if ($newsettings->{'captcha'} eq 'recaptcha') { $newpub = $env{'form.'.$container.'_recaptchapub'}; $newpriv = $env{'form.'.$container.'_recaptchapriv'}; @@ -9445,6 +9661,12 @@ sub process_captcha { public => $newpub, private => $newpriv, }; + $newversion = $env{'form.'.$container.'_recaptchaversion'}; + $newversion =~ s/\D//g; + if ($newversion ne '2') { + $newversion = 1; + } + $newsettings->{'recaptchaversion'} = $newversion; } if (ref($current->{'recaptchakeys'}) eq 'HASH') { $currpub = $current->{'recaptchakeys'}{'public'}; @@ -9456,6 +9678,23 @@ sub process_captcha { } } } + if ($current->{'captcha'} eq 'recaptcha') { + $currversion = $current->{'recaptchaversion'}; + if ($currversion ne '2') { + $currversion = 1; + } + } + if ($currversion ne $newversion) { + if ($container eq 'cancreate') { + if (ref($changes->{'cancreate'}) eq 'ARRAY') { + push(@{$changes->{'cancreate'}},'recaptchaversion'); + } elsif (!defined($changes->{'cancreate'})) { + $changes->{'cancreate'} = ['recaptchaversion']; + } + } else { + $changes->{'recaptchaversion'} = 1; + } + } if (($newpub ne $currpub) || ($newpriv ne $currpriv)) { if ($container eq 'cancreate') { if (ref($changes->{'cancreate'}) eq 'ARRAY') { @@ -10293,30 +10532,76 @@ sub modify_helpsettings { my %defaultchecked = ('submitbugs' => 'on'); my @offon = ('off','on'); my @toggles = ('submitbugs'); + my %current = ('submitbugs' => ''); if (ref($domconfig{'helpsettings'}) eq 'HASH') { - foreach my $item (@toggles) { - if ($defaultchecked{$item} eq 'on') { - if ($domconfig{'helpsettings'}{$item} eq '') { - if ($env{'form.'.$item} eq '0') { - $changes{$item} = 1; - } - } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { + %current = %{$domconfig{'helpsettings'}}; + } + foreach my $item (@toggles) { + if ($defaultchecked{$item} eq 'on') { + if ($current{$item} eq '') { + if ($env{'form.'.$item} eq '0') { $changes{$item} = 1; } - } elsif ($defaultchecked{$item} eq 'off') { - if ($domconfig{'helpsettings'}{$item} eq '') { - if ($env{'form.'.$item} eq '1') { - $changes{$item} = 1; - } - } elsif ($domconfig{'helpsettings'}{$item} ne $env{'form.'.$item}) { + } elsif ($current{$item} ne $env{'form.'.$item}) { + $changes{$item} = 1; + } + } elsif ($defaultchecked{$item} eq 'off') { + if ($current{$item} eq '') { + if ($env{'form.'.$item} eq '1') { $changes{$item} = 1; } + } elsif ($current{$item} ne $env{'form.'.$item}) { + $changes{$item} = 1; + } + } + if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) { + $helphash{'helpsettings'}{$item} = $env{'form.'.$item}; + } + } + + my @modify = &Apache::loncommon::get_env_multiple('form.modifycusthelp'); + my $confname = $dom.'-domainconfig'; + my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_'); + if (@modify) { + foreach my $num (@modify) { + my $rolename = $env{'form.custhelprole'.$num}; + if ($rolename ne '') { + if (exists($existing{'rolesdef_'.$rolename})) { + my $prefix = 'custhelp'.$num; + my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$prefix); + my %currprivs; + ($currprivs{'s'},$currprivs{'d'},$currprivs{'c'}) = + split(/\_/,$existing{'rolesdef_'.$rolename}); + foreach my $level ('c','d','s') { + if ($newprivs{$level} ne $currprivs{$level}) { + $changes{'customrole'}{$rolename} = 1; + my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'}, + $newprivs{'c'},$confname,$dom); + last; + } + } + } } - if (($env{'form.'.$item} eq '0') || ($env{'form.'.$item} eq '1')) { - $helphash{'helpsettings'}{$item} = $env{'form.'.$item}; + } + } + if ($env{'form.newcusthelp'} ne '') { + my $prefix = 'custhelp'.$env{'form.newcusthelp'}; + my $rolename = $env{'form.newcusthelpname'}; + $rolename=~s/[^A-Za-z0-9]//gs; + if ($rolename ne '') { + unless(exists($existing{'rolesdef_'.$rolename})) { + my $errmsg; + my $result = &Apache::lonuserutils::store_custom_role($rolename,$prefix, + $confname,$dom); + if ($result eq 'ok') { + $changes{'newcustomrole'} = $rolename; + } else { + $errmsg = ': '.$result; + } } } } + my $putresult; if (keys(%changes) > 0) { $putresult = &Apache::lonnet::put_dom('configuration',\%helphash,$dom); @@ -10327,6 +10612,16 @@ sub modify_helpsettings { $resulttext .= '
  • '.&mt('Display link to: [_1] set to "'.$offon[$env{'form.'.$item}].'".', &Apache::loncommon::modal_link('http://bugs.loncapa.org', &mt('LON-CAPA bug tracker'),600,500)).'
  • '; + } elsif ($item eq 'customrole') { + if (ref($changes{'customrole'}) eq 'HASH') { + foreach my $role (sort(keys(%{$changes{'customrole'}}))) { + $resulttext .= '
  • '.&mt('Existing custom role modified: [_1]', + $role).'
  • '; + } + } + } elsif ($item eq 'newcustomrole') { + $resulttext .= '
  • '.&mt('New custom role added: [_1]', + $changes{'newcustomrole'}).'
  • '; } } $resulttext .= ''; @@ -10353,12 +10648,14 @@ sub modify_coursedefaults { ); my @toggles = ('uselcmath','usejsme'); my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial', - 'uploadquota_community','uploadquota_textbook'); + 'uploadquota_community','uploadquota_textbook','mysqltables_official', + 'mysqltables_unofficial','mysqltables_community','mysqltables_textbook'); my @types = ('official','unofficial','community','textbook'); my %staticdefaults = ( anonsurvey_threshold => 10, uploadquota => 500, postsubmit => 60, + mysqltables => 172800, ); $defaultshash{'coursedefaults'} = {}; @@ -10399,12 +10696,12 @@ sub modify_coursedefaults { } $defaultshash{'coursedefaults'}{$item} = $newdef; } else { - my ($type) = ($item =~ /^\Quploadquota_\E(\w+)$/); - if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') { - $currdef = $domconfig{'coursedefaults'}{'uploadquota'}{$type}; + my ($setting,$type) = ($item =~ /^(uploadquota|mysqltables)_(\w+)$/); + if (ref($domconfig{'coursedefaults'}{$setting}) eq 'HASH') { + $currdef = $domconfig{'coursedefaults'}{$setting}{$type}; } $newdef =~ s/[^\w.\-]//g; - $defaultshash{'coursedefaults'}{'uploadquota'}{$type} = $newdef; + $defaultshash{'coursedefaults'}{$setting}{$type} = $newdef; } if ($currdef ne $newdef) { my $staticdef; @@ -10412,9 +10709,10 @@ sub modify_coursedefaults { unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) { $changes{$item} = 1; } - } else { - unless (($currdef eq '') && ($newdef == $staticdefaults{'uploadquota'})) { - $changes{'uploadquota'} = 1; + } elsif ($item =~ /^(uploadquota|mysqltables)_/) { + my $setting = $1; + unless (($currdef eq '') && ($newdef == $staticdefaults{$setting})) { + $changes{$setting} = 1; } } } @@ -10539,7 +10837,7 @@ sub modify_coursedefaults { my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); if (($changes{'uploadquota'}) || ($changes{'postsubmit'}) || ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) || - ($changes{'canclone'})) { + ($changes{'canclone'}) || ($changes{'mysqltables'})) { foreach my $item ('uselcmath','usejsme') { if ($changes{$item}) { $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item}; @@ -10618,6 +10916,18 @@ sub modify_coursedefaults { } else { $resulttext .= '
  • '.&mt('Default quota for content uploaded via Course Editor remains default: [_1] MB',$staticdefaults{'uploadquota'}).'
  • '; } + } elsif ($item eq 'mysqltables') { + if (ref($defaultshash{'coursedefaults'}{'mysqltables'}) eq 'HASH') { + $resulttext .= '
  • '.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver').''. + '
  • '; + } else { + $resulttext .= '
  • '.&mt('Lifetime of "Temporary" MySQL tables (student performance data) on homeserver remains default: [_1] s',$staticdefaults{'uploadquota'}).'
  • '; + } } elsif ($item eq 'postsubmit') { if ($domdefaults{'postsubmit'} eq 'off') { $resulttext .= '
  • '.&mt('Submit button(s) remain enabled on page after student makes submission.'); @@ -12136,6 +12446,8 @@ function updateCaptcha(caller,context) { var pubitem; var privtext; var pubtext; + var versionitem; + var versiontext; if (document.getElementById(context+'_recaptchapub')) { pubitem = document.getElementById(context+'_recaptchapub'); } else { @@ -12156,6 +12468,16 @@ function updateCaptcha(caller,context) { } else { return; } + if (document.getElementById(context+'_recaptchaversion')) { + versionitem = document.getElementById(context+'_recaptchaversion'); + } else { + return; + } + if (document.getElementById(context+'_recaptchavertxt')) { + versiontext = document.getElementById(context+'_recaptchavertxt'); + } else { + return; + } if (caller.checked) { if (caller.value == 'recaptcha') { pubitem.type = 'text'; @@ -12164,11 +12486,16 @@ function updateCaptcha(caller,context) { privitem.size = '40'; pubtext.innerHTML = "$lt{'pub'}"; privtext.innerHTML = "$lt{'priv'}"; + versionitem.type = 'text'; + versionitem.size = '3'; + versiontext.innerHTML = "$lt{'ver'}"; } else { pubitem.type = 'hidden'; privitem.type = 'hidden'; + versionitem.type = 'hidden'; pubtext.innerHTML = ''; privtext.innerHTML = ''; + versiontext.innerHTML = ''; } } return; @@ -12234,6 +12561,7 @@ sub captcha_phrases { original => 'original (CAPTCHA)', recaptcha => 'successor (ReCAPTCHA)', notused => 'unused', + ver => 'ReCAPTCHA version (1 or 2)', ); }