--- loncom/interface/domainprefs.pm 2017/05/10 13:49:14 1.298 +++ loncom/interface/domainprefs.pm 2017/11/30 01:49:19 1.317 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set domain-wide configuration settings # -# $Id: domainprefs.pm,v 1.298 2017/05/10 13:49:14 raeburn Exp $ +# $Id: domainprefs.pm,v 1.317 2017/11/30 01:49:19 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -281,7 +281,7 @@ sub handler { {col1 => 'Internal Authentication', col2 => 'Value'}, {col1 => 'Institutional user types', - col2 => 'Assignable to e-mail usernames'}], + col2 => 'Name displayed'}], print => \&print_defaults, modify => \&modify_defaults, }, @@ -363,7 +363,7 @@ sub handler { col2 => 'Enabled?'}, {col1 => 'Institutional user type (login/SSO self-creation)', col2 => 'Information user can enter'}, - {col1 => 'Self-creation with e-mail as username', + {col1 => 'Self-creation with e-mail verification', col2 => 'Settings'}], print => \&print_selfcreation, modify => \&modify_selfcreation, @@ -598,6 +598,9 @@ $javascript_validations $coursebrowserjs END } + if (grep(/^selfcreation$/,@actions)) { + $js .= &selfcreate_javascript(); + } if (grep(/^contacts$/,@actions)) { $js .= &contacts_javascript(); } @@ -694,7 +697,7 @@ sub process_changes { } elsif ($action eq 'usercreation') { $output = &modify_usercreation($dom,%domconfig); } elsif ($action eq 'selfcreation') { - $output = &modify_selfcreation($dom,%domconfig); + $output = &modify_selfcreation($dom,$lastactref,%domconfig); } elsif ($action eq 'usermodification') { $output = &modify_usermodification($dom,%domconfig); } elsif ($action eq 'contacts') { @@ -759,7 +762,7 @@ sub print_config_box { $output .= ' - '."\n". ''; @@ -975,8 +978,8 @@ sub print_config_box {
'. + '. &mt($item->{text}).' '. &Apache::loncommon::help_open_topic($item->{'help'}).'
- - + + '. &print_validation_rows('requestcourses',$dom,$settings,\$rowtotal); } elsif ($action eq 'requestauthor') { @@ -991,9 +994,9 @@ sub print_config_box {
'.&mt($item->{'header'}->[4]->{'col1'}).''.&mt($item->{'header'}->[4]->{'col2'}).''.&mt($item->{'header'}->[4]->{'col1'}).''.&mt($item->{'header'}->[4]->{'col2'}).'
- - '. &print_rolecolors($phase,'author',$dom,$confname,$settings,\$rowtotal).' @@ -1021,30 +1024,30 @@ sub print_config_box { '; } elsif ($action eq 'serverstatuses') { $output .= ' - '; } else { $output .= ' - '; + '; } if (defined($item->{'header'}->[0]->{'col3'})) { - $output .= ''; if ($item->{'header'}->[0]->{'col3'}) { if (defined($item->{'header'}->[0]->{'col4'})) { - $output .= ''; } if ($item->{'header'}->[0]->{'col4'}) { - $output .= ''; @@ -1086,7 +1089,7 @@ sub print_login { my $choice = $choices{'disallowlogin'}; $css_class = ' class="LC_odd_row"'; $datatable .= ''. - '
'. + '. &mt($item->{'header'}->[2]->{'col1'}).''. + '. &mt($item->{'header'}->[2]->{'col2'}).'
'.&mt($item->{'header'}->[0]->{'col1'}).''.&mt($item->{'header'}->[0]->{'col1'}). + '.&mt($item->{'header'}->[0]->{'col1'}). '
('.&mt('Automatic access for Dom. Coords.').')
'.&mt($item->{'header'}->[0]->{'col1'}).''.&mt($item->{'header'}->[0]->{'col1'}).''. + $output .= ''. &mt($item->{'header'}->[0]->{'col2'}); if ($action eq 'serverstatuses') { $output .= '
('.&mt('user1:domain1,user2:domain2 etc.').')'; } } else { - $output .= '
'. + $output .= ''. &mt($item->{'header'}->[0]->{'col2'}); } $output .= ''. + $output .= ''. &mt($item->{'header'}->[0]->{'col3'}); } else { - $output .= ''. + $output .= ''. &mt($item->{'header'}->[0]->{'col3'}); } if ($action eq 'serverstatuses') { @@ -1053,7 +1056,7 @@ sub print_config_box { $output .= ''. + $output .= ''. &mt($item->{'header'}->[0]->{'col4'}); } $output .= '
'.$choice.''. + '
'.$choices{'hostid'}.''. ''. ''. ''. @@ -1367,7 +1370,7 @@ sub print_login { my $choice = $choices{'headtag'}; $css_class = ' class="LC_odd_row"'; $datatable .= ''. - '
'.$choices{'hostid'}.''.$choices{'server'}.''.$choices{'serverpath'}.''.$choices{'custompath'}.''.$choice.''. + '
'.$choices{'hostid'}.''. ''. ''. ''."\n"; @@ -1653,7 +1656,8 @@ sub display_color_options { if ($fullwidth ne '' && $fullheight ne '') { if ($fullwidth > $width && $fullheight > $height) { my $size = $width.'x'.$height; - system("convert -sample $size $input $output"); + my @args = ('convert','-sample',$size,$input,$output); + system({$args[0]} @args); $showfile = "/$imgdir/tn-".$filename; } } @@ -1723,7 +1727,7 @@ sub display_color_options { '
'.$choices{'hostid'}.''.$choices{'current'}.''.$choices{'action'}.''.$choices{'exempt'}.'
'; foreach my $item (@{$bgs}) { - $datatable .= '
'.$choices->{$item}; + $datatable .= ''.$choices->{$item}; my $color = $designs->{'bgs'}{$item} ? $designs->{'bgs'}{$item} : $defaults->{'bgs'}{$item}; if ($designs->{'bgs'}{$item}) { $datatable .= ' '; @@ -1751,7 +1755,7 @@ sub display_color_options { ''; foreach my $item (@{$links}) { my $color = $designs->{'links'}{$item} ? $designs->{'links'}{$item} : $defaults->{'links'}{$item}; - $datatable .= '
'.$choices->{$item}."\n"; + $datatable .= ''.$choices->{$item}."\n"; if ($designs->{'links'}{$item}) { $datatable.=' '; } @@ -1812,7 +1816,7 @@ sub login_text_colors { my ($img,$role,$logintext,$phase,$choices,$designs,$defaults) = @_; my $color_menu = ''; foreach my $item (@{$logintext}) { - $color_menu .= ''; @@ -1847,7 +1851,7 @@ sub image_changes { $role.'_del_'.$img.'" value="1" />'.&mt('Delete?'). ' '.&mt('Replace:').'
'; } else { - $output .= ''; $rownum ++; } - } else { + } elsif ($position eq 'bottom') { + $css_class = $rownum%2?' class="LC_odd_row"':''; + $datatable .= ''. + ''."\n"; + $rownum ++; + } + unless ($position eq 'top') { foreach my $type (@mailings) { $css_class = $rownum%2?' class="LC_odd_row"':''; $datatable .= ''. @@ -3168,56 +3232,138 @@ sub print_contacts { \%choices,$rownum); $datatable .= $reports; } elsif ($position eq 'bottom') { - $css_class = $rownum%2?' class="LC_odd_row"':''; - $datatable .= ''. - ''."\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)',"$typetitle"); + $output = ''. + "\n". + ''."\n"; + return $output; +} + sub contacts_javascript { return <<"ENDSCRIPT"; @@ -3235,6 +3381,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 @@ -3261,8 +3438,10 @@ sub print_helpsettings { my $css_class; my %existing=&Apache::lonnet::dump('roles',$dom,$confname,'rolesdef_'); my (%customroles,%ordered,%current); - if (ref($settings->{'adhoc'}) eq 'HASH') { - %current = %{$settings->{'adhoc'}}; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'adhoc'}) eq 'HASH') { + %current = %{$settings->{'adhoc'}}; + } } my $count = 0; foreach my $key (sort(keys(%existing))) { @@ -3338,7 +3517,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 .= ''; if ($align eq 'left') { @@ -3706,7 +3885,7 @@ sub print_ltitools { 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,$version); + my ($title,$key,$secret,$url,$imgsrc); if (ref($settings->{$item}) eq 'HASH') { $title = $settings->{$item}->{'title'}; $url = $settings->{$item}->{'url'}; @@ -3847,7 +4026,7 @@ sub print_ltitools { if (!$rolemaps{$role}) { $selectnone = ' selected="selected"'; } - $datatable .= '
'.$choices->{$item}; + $color_menu .= ''.$choices->{$item}; my $color = $designs->{'logintext'}{$item} ? $designs->{'logintext'}{$item} : $defaults->{'logintext'}{$item}; $color_menu .= '
'.$logincolors.&mt('Upload:').'
'; + $output .= '
'.$logincolors.&mt('Upload:').'
'; } } return $output; @@ -2279,7 +2283,7 @@ sub print_quotas { } sub print_requestmail { - my ($dom,$action,$settings,$rowtotal) = @_; + my ($dom,$action,$settings,$rowtotal,$customcss,$rowstyle) = @_; my ($now,$datatable,%currapp); $now = time; if (ref($settings) eq 'HASH') { @@ -2291,7 +2295,19 @@ sub print_requestmail { } my $numinrow = 2; my $css_class; - $css_class = ($$rowtotal%2? ' class="LC_odd_row"':''); + if ($$rowtotal%2) { + $css_class = 'LC_odd_row'; + } + if ($customcss) { + $css_class .= " $customcss"; + } + $css_class =~ s/^\s+//; + if ($css_class) { + $css_class = ' class="'.$css_class.'"'; + } + if ($rowstyle) { + $css_class .= ' style="'.$rowstyle.'"'; + } my $text; if ($action eq 'requestcourses') { $text = &mt('Receive notification of course requests requiring approval'); @@ -2764,7 +2780,7 @@ sub print_autoupdate { my $locknamesettings; $datatable .= &insttypes_row($settings,$types,$usertypes, $dom,$numinrow,$othertitle, - 'lockablenames'); + 'lockablenames',$rowtotal); $$rowtotal ++; } else { my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); @@ -2907,7 +2923,8 @@ sub print_directorysrch { if (ref($usertypes) eq 'HASH') { if (keys(%{$usertypes}) > 0) { $datatable .= &insttypes_row($settings,$types,$usertypes,$dom, - $numinrow,$othertitle,'cansearch'); + $numinrow,$othertitle,'cansearch', + $rowtotal); $cansrchrow = 1; } } @@ -3108,7 +3125,54 @@ sub print_contacts { $to{$item}.'" />
'.&mt('Extra helpdesk form fields:').'
'. + &mt('(e-mail, subject, and description always shown)'). + '
'; + if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') && + (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) { + $datatable .= ''; + foreach my $field (@{$fields}) { + $datatable .= ''. + ''; + } + $datatable .= '
'.&mt('Field').''.&mt('Status').'
'.$fieldtitles->{$field}; + if (($field eq 'screenshot') || ($field eq 'cc')) { + $datatable .= ' '.&mt('(logged-in users)'); + } + $datatable .=''; + 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 .= ''.(' 'x2); + } + } + if ($field eq 'screenshot') { + my $display; + if ($currfield{$field} eq 'no') { + $display = ' style="display:none"'; + } + $datatable .= '
'.&mt('Maximum size for upload (MB)').''. + ''; + } + $datatable .= '
'; + } + $datatable .= '
'.&mt('Extra helpdesk form fields:').'
'. - &mt('(e-mail, subject, and description always shown)'). - '
'; - if ((ref($fields) eq 'ARRAY') && (ref($fieldtitles) eq 'HASH') && - (ref($fieldoptions) eq 'HASH') && (ref($possoptions) eq 'HASH')) { - $datatable .= ''; - foreach my $field (@{$fields}) { - $datatable .= ''. - ''; } - $datatable .= '
'.&mt('Field').''.&mt('Status').'
'.$fieldtitles->{$field}; - if (($field eq 'screenshot') || ($field eq 'cc')) { - $datatable .= ' '.&mt('(logged-in users)'); - } - $datatable .=''; - 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 .= ''.(' 'x2); } } - if ($field eq 'screenshot') { - my $display; - if ($currfield{$field} eq 'no') { - $display = ' style="display:none"'; - } - $datatable .= '
'.&mt('Maximum size for upload (MB)').''. - ''; + } + 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 .= '
'; } - $datatable .= '
$description'. + '
'.&mt('E-mail recipient(s)').''. + ''; + 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 .= ' '; + } + } + $output .= '
'.&mt('Others').':  '. + ''; + my %locchecked; + foreach my $loc ('s','b') { + if ($includeloc eq $loc) { + $locchecked{$loc} = ' checked="checked"'; + last; + } + } + $output .= '
'.&mt('Bcc:').(' 'x6). + '
'. + '
'.&mt('Optional added text').''. + &mt('Text automatically added to e-mail:').' '. + '
'. + ''.&mt('Location:').' '. + ''. + (' 'x2). + ''. + '
'. + '
'.$role.'
'. + $datatable .= '
'.$role.'
'. '
'. + ''. ''.$choices->{$item}. ''. + $datatable .= ''. &Apache::lonnet::plaintext($role,'Course').'
'. ''; foreach my $role (@courseroles) { my ($checked,$checkednone); - $datatable .= ''."\n"; + $itemcount ++; ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked, \%choices,$itemcount); + $datatable = $mathdisp.$datatable; $css_class = $itemcount%2?' class="LC_odd_row"':''; $datatable .= - ''. - '
'. + $datatable .= ''. &Apache::lonnet::plaintext($role,'Course').'
'. '
'. + ''.$choices{'texengine'}. + ''. + '
'. + ''. ''.$choices{'canclone'}. ''; my $currcanclone = 'none'; @@ -4121,7 +4330,7 @@ sub print_coursedefaults { if ($checked) { $show = 'block'; } - $additional = '
'. + $additional = '
'. &mt('Institutional codes for new and cloned course have identical:'). '
'; foreach my $item (@code_order) { @@ -4229,10 +4438,10 @@ sub print_coursedefaults { $datatable .= '
'. $choices{'uploadquota'}. ''. + ''. ''; foreach my $type (@types) { - $datatable .= ''; } @@ -4247,7 +4456,7 @@ sub print_coursedefaults { ''.&mt('Default credits').'
'.&mt($type).'
'. + $datatable .= '
'.&mt($type).'
'. '
'; foreach my $type (@types) { next if ($type eq 'community'); - $additional .= ''; } @@ -4271,7 +4480,7 @@ sub print_coursedefaults { ''.&mt('Enter 0 to remain disabled until page reload.').'
'. '
'.&mt($type).'
'. + $additional .= '
'.&mt($type).'
'. '
'; foreach my $type (@types) { - $additional .= ''; } @@ -4289,10 +4498,10 @@ sub print_coursedefaults { $datatable .= ''. - '
'.&mt($type).'
'. + $additional .= '
'.&mt($type).'
'. '
'. $choices{'mysqltables'}. ''. + ''. ''; foreach my $type (@types) { - $datatable .= ''; } @@ -5191,7 +5400,7 @@ sub print_loadbalancing { my $disabled_div_style = 'display: block'; my $homedom_div_style = 'display: none'; $datatable .= ''. - ''."\n". '\n". + '\n"; return $output; } sub captcha_choice { - my ($context,$settings,$itemcount) = @_; + my ($context,$settings,$itemcount,$customcss,$rowstyle) = @_; my ($keyentry,$currpub,$currpriv,%checked,$rowname,$pubtext,$privtext, $vertext,$currver); my %lt = &captcha_phrases(); @@ -6002,7 +6501,20 @@ sub captcha_choice { } else { $checked{'original'} = ' checked="checked"'; } - my $css_class = $itemcount%2?' class="LC_odd_row"':''; + my $css_class; + if ($itemcount%2) { + $css_class = 'LC_odd_row'; + } + if ($customcss) { + $css_class .= " $customcss"; + } + $css_class =~ s/^\s+//; + if ($css_class) { + $css_class = ' class="'.$css_class.'"'; + } + if ($rowstyle) { + $css_class .= ' style="'.$rowstyle.'"'; + } my $output = ''. ''; return $output; } @@ -8387,7 +8940,7 @@ sub display_colorchgs { } else { my $newitem = $confhash->{$role}{$item}; if ($key eq 'images') { - $newitem = ''.$choices{$item}.''; + $newitem = ''.$choices{$item}.''; } $resulttext .= '
  • '.&mt("$choices{$item} set to [_1]",$newitem).'
  • '; } @@ -8514,14 +9067,14 @@ sub publishlogo { } else { my $source = $filepath.'/'.$file; my $logfile; - if (!open($logfile,">>$source".'.log')) { + if (!open($logfile,">>",$source.'.log')) { return (&mt('No write permission to Authoring Space')); } print $logfile "\n================= Publish ".localtime()." ================\n". $env{'user.name'}.':'.$env{'user.domain'}."\n"; # Save the file - if (!open(FH,'>'.$source)) { + if (!open(FH,">",$source)) { &Apache::lonnet::logthis('Failed to create '.$source); return (&mt('Failed to create file')); } @@ -8582,7 +9135,8 @@ $env{'user.name'}.':'.$env{'user.domain' if ($fullwidth ne '' && $fullheight ne '') { if ($fullwidth > $thumbwidth && $fullheight > $thumbheight) { my $thumbsize = $thumbwidth.'x'.$thumbheight; - system("convert -sample $thumbsize $inputfile $outfile"); + my @args = ('convert','-sample',$thumbsize,$inputfile,$outfile); + system({$args[0]} @args); chmod(0660, $filepath.'/tn-'.$file); if (-e $outfile) { my $copyfile=$targetdir.'/tn-'.$file; @@ -8662,7 +9216,7 @@ sub write_metadata { { print $logfile "\nWrite metadata file for ".$targetdir.'/'.$file; my $mfh; - if (open($mfh,'>'.$targetdir.'/'.$file.'.meta')) { + if (open($mfh,">",$targetdir.'/'.$file.'.meta')) { foreach (sort(keys(%metadatafields))) { unless ($_=~/\./) { my $unikey=$_; @@ -8696,7 +9250,7 @@ sub notifysubscribed { next unless (ref($targetsource) eq 'ARRAY'); my ($target,$source)=@{$targetsource}; if ($source ne '') { - if (open(my $logfh,'>>'.$source.'.log')) { + if (open(my $logfh,">>",$source.'.log')) { print $logfh "\nCleanup phase: Notifications\n"; my @subscribed=&subscribed_hosts($target); foreach my $subhost (@subscribed) { @@ -8722,7 +9276,7 @@ sub notifysubscribed { sub subscribed_hosts { my ($target) = @_; my @subscribed; - if (open(my $fh,"<$target.subscription")) { + if (open(my $fh,"<","$target.subscription")) { while (my $subline=<$fh>) { if ($subline =~ /^($match_lonid):/) { my $host = $1; @@ -8921,17 +9475,21 @@ sub modify_quotas { #FIXME need to obsolete item in RES space } elsif ($env{'form.'.$type.'_image_'.$i.'.filename'}) { my ($cdom,$cnum) = split(/_/,$key); - my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i, - $cdom,$cnum,$type,$configuserok, - $switchserver,$author_ok); - if ($imgurl) { - $confhash{$type}{$key}{'image'} = $imgurl; - $changes{$type}{$key} = 1; - } - if ($error) { - &Apache::lonnet::logthis($error); - $errors .= '
  • '.$error.'
  • '; - } + if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') { + $errors .= '
  • '.&mt('Image not saved: could not find textbook course').'
  • '; + } else { + my ($imgurl,$error) = &process_textbook_image($r,$dom,$confname,$type.'_image_'.$i, + $cdom,$cnum,$type,$configuserok, + $switchserver,$author_ok); + if ($imgurl) { + $confhash{$type}{$key}{'image'} = $imgurl; + $changes{$type}{$key} = 1; + } + if ($error) { + &Apache::lonnet::logthis($error); + $errors .= '
  • '.$error.'
  • '; + } + } } elsif ($domconfig{$action}{$type}{$key}{'image'}) { $confhash{$type}{$key}{'image'} = $domconfig{$action}{$type}{$key}{'image'}; @@ -8964,15 +9522,19 @@ sub modify_quotas { if ($type eq 'textbooks') { if ($env{'form.'.$type.'_addbook_image.filename'} ne '') { my ($cdom,$cnum) = split(/_/,$newbook{$type}); - my ($imageurl,$error) = - &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type, - $configuserok,$switchserver,$author_ok); - if ($imageurl) { - $confhash{$type}{$newbook{$type}}{'image'} = $imageurl; - } - if ($error) { - &Apache::lonnet::logthis($error); - $errors .= '
  • '.$error.'
  • '; + if (&Apache::lonnet::homeserver($cnum,$cdom) eq 'no_host') { + $errors .= '
  • '.&mt('Image not saved: could not find textbook course').'
  • '; + } else { + my ($imageurl,$error) = + &process_textbook_image($r,$dom,$confname,$type.'_addbook_image',$cdom,$cnum,$type, + $configuserok,$switchserver,$author_ok); + if ($imageurl) { + $confhash{$type}{$newbook{$type}}{'image'} = $imageurl; + } + if ($error) { + &Apache::lonnet::logthis($error); + $errors .= '
  • '.$error.'
  • '; + } } } } @@ -9464,7 +10026,7 @@ sub process_textbook_image { } elsif ($author_ok eq 'ok') { my ($result,$imageurl) = &publishlogo($r,'upload',$caller,$dom,$confname, - "$type/$dom/$cnum/cover",$width,$height); + "$type/$cdom/$cnum/cover",$width,$height); if ($result eq 'ok') { $url = $imageurl; } else { @@ -9547,7 +10109,7 @@ sub modify_ltitools { } if ($env{'form.ltitools_add_image.filename'} ne '') { my ($imageurl,$error) = - &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$dom, + &process_ltitools_image($r,$dom,$confname,'ltitools_add_image',$newid, $configuserok,$switchserver,$author_ok); if ($imageurl) { $confhash{$newid}{'image'} = $imageurl; @@ -9610,6 +10172,7 @@ sub modify_ltitools { 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'}) { @@ -9966,7 +10529,7 @@ sub modify_ltitools { } } if ($customlist) { - $resulttext .= '
  • '.&mt('Custom items').':'.$customlist.'
  • '; + $resulttext .= '
  • '.&mt('Custom items').': '.$customlist.'
  • '; } } $resulttext .= ''; @@ -10147,9 +10710,9 @@ sub modify_autoenroll { } if ($changes{'autofailsafe'}) { if ($failsafe ne '') { - $resulttext .= '
  • '.&mt("$title{'failsafe'} set to [_1]",$failsafe).'
  • '; + $resulttext .= '
  • '.&mt('Failsafe for no drops if institutional data missing for a section set to: [_1]',$failsafe).'
  • '; } else { - $resulttext .= '
  • '.&mt("$title{'failsafe'} deleted"); + $resulttext .= '
  • '.&mt('Failsafe for no drops if institutional data missing for a section: deleted'); } &Apache::lonnet::get_domain_defaults($dom,1); if (ref($lastactref) eq 'HASH') { @@ -10687,17 +11250,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}) { @@ -10752,6 +11355,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'}; @@ -10866,6 +11496,60 @@ sub modify_contacts { $resulttext .= '
  • '; } } + if (ref($changes{'overrides'}) eq 'ARRAY') { + my @deletions; + foreach my $type (@{$changes{'overrides'}}) { + if ($usertypeshash{$type}) { + if (grep(/^\Q$type\E/,@overrides)) { + $resulttext .= '
  • '.&mt("Overrides based on requester's affiliation set for [_1]", + $usertypeshash{$type}).'
    • '; + 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]', + ''.join(', ',@text).''); + } + if ($newsetting{'override_'.$type}{'bcc'} ne '') { + my $bcctext; + if (@text) { + $bcctext = ' '.&mt('with Bcc to'); + } else { + $bcctext = '(Bcc)'; + } + $resulttext .= $bcctext.': '.$newsetting{'override_'.$type}{'bcc'}.''; + } elsif (!@text) { + $resulttext .= &mt('Helpdesk e-mail sent to no one'); + } + $resulttext .= '
    • '; + if ($newsetting{'override_'.$type}{'include'} ne '') { + my ($loc,$str) = split(/:/,$newsetting{'override_'.$type}{'include'}); + if ($loc eq 'b') { + $resulttext .= '
    • '.&mt('Text automatically added to e-mail body:').' '.&unescape($str).'
    • '; + } elsif ($loc eq 's') { + $resulttext .= '
    • '.&mt('Text automatically added to e-mail subject:').' '.&unescape($str).'
    • '; + } + } + } + $resulttext .= '
  • '; + } else { + push(@deletions,$usertypeshash{$type}); + } + } + } + if (@deletions) { + $resulttext .= '
  • '.&mt("Overrides based on requester's affiliation discontinued for: [_1]", + join(', ',@deletions)).'
  • '; + } + } my @offon = ('off','on'); if ($changes{'reporterrors'}) { $resulttext .= '
  • '. @@ -10921,7 +11605,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'}). '
  • '; - } } $resulttext .= ''; @@ -10944,12 +11627,10 @@ sub modify_usercreation { if ($key eq 'cancreate') { 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 'recaptchaversion')) { - $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item}; - } else { + if (($item eq 'requestcrs') || ($item eq 'course') || ($item eq 'author')) { $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item}; + } else { + $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item}; } } } @@ -11152,14 +11833,18 @@ sub modify_usercreation { } sub modify_selfcreation { - my ($dom,%domconfig) = @_; - my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%changes,%cancreate); - my (%save_usercreate,%save_usermodify); - my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - if (ref($types) eq 'ARRAY') { - $usertypes->{'default'} = $othertitle; - push(@{$types},'default'); + my ($dom,$lastactref,%domconfig) = @_; + my ($resulttext,$warningmsg,%curr_usercreation,%curr_usermodify,%curr_inststatus,%changes,%cancreate); + my (%save_usercreate,%save_usermodify,%save_inststatus,@types,%usertypes); + my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); + my ($othertitle,$usertypesref,$typesref) = &Apache::loncommon::sorted_inst_types($dom); + if (ref($typesref) eq 'ARRAY') { + @types = @{$typesref}; + } + if (ref($usertypesref) eq 'HASH') { + %usertypes = %{$usertypesref}; } + $usertypes{'default'} = $othertitle; # # Retrieve current domain configuration for self-creation of usernames from $domconfig{'usercreation'}. # @@ -11169,10 +11854,11 @@ sub modify_selfcreation { 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 'recaptchaversion') || - ($item eq 'emailusername') || ($item eq 'notify') || - ($item eq 'selfcreateprocessing') || ($item eq 'shibenv')) { + ($item eq 'captcha') || ($item eq 'recaptchakeys') || + ($item eq 'recaptchaversion') || ($item eq 'notify') || + ($item eq 'emailusername') || ($item eq 'shibenv') || + ($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || + ($item eq 'emailoptions') || ($item eq 'emaildomain')) { $curr_usercreation{$key}{$item} = $domconfig{'usercreation'}{$key}{$item}; } else { $save_usercreate{$key}{$item} = $domconfig{'usercreation'}{$key}{$item}; @@ -11198,41 +11884,160 @@ sub modify_selfcreation { } } } +# +# Retrieve current domain configuration for institutional status types from $domconfig{'inststatus'}. +# + if (ref($domconfig{'inststatus'}) eq 'HASH') { + foreach my $key (keys(%{$domconfig{'inststatus'}})) { + if ($key eq 'inststatusguest') { + $curr_inststatus{$key} = $domconfig{'inststatus'}{$key}; + } else { + $save_inststatus{$key} = $domconfig{'inststatus'}{$key}; + } + } + } my @contexts = ('selfcreate'); @{$cancreate{'selfcreate'}} = (); %{$cancreate{'emailusername'}} = (); - @{$cancreate{'statustocreate'}} = (); + if (@types) { + @{$cancreate{'statustocreate'}} = (); + } %{$cancreate{'selfcreateprocessing'}} = (); %{$cancreate{'shibenv'}} = (); + %{$cancreate{'emailverified'}} = (); + %{$cancreate{'emailoptions'}} = (); + %{$cancreate{'emaildomain'}} = (); my %selfcreatetypes = ( sso => 'users authenticated by institutional single sign on', login => 'users authenticated by institutional log-in', - email => 'users who provide a valid e-mail address for use as username', + email => 'users verified by e-mail', ); # # 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; - if (ref($domconfig{'inststatus'}) eq 'HASH') { - if (ref($domconfig{'inststatus'}{'inststatusguest'}) eq 'ARRAY') { - @statuses = @{$domconfig{'inststatus'}{'inststatusguest'}}; - } - } - push(@statuses,'default'); - + my (@statuses,%email_rule); foreach my $item ('login','sso','email') { if ($item eq 'email') { if ($env{'form.cancreate_email'}) { - push(@{$cancreate{'selfcreate'}},'email'); - push(@contexts,'selfcreateprocessing'); - foreach my $type (@statuses) { - if ($type eq 'default') { - $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess'}; - } else { - $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type}; + if (@types) { + my @poss_statuses = &Apache::loncommon::get_env_multiple('form.selfassign'); + foreach my $status (@poss_statuses) { + if (grep(/^\Q$status\E$/,(@types,'default'))) { + push(@statuses,$status); + } + } + $save_inststatus{'inststatusguest'} = \@statuses; + } else { + push(@statuses,'default'); + } + if (@statuses) { + my %curr_rule; + if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') { + foreach my $type (@statuses) { + $curr_rule{$type} = $curr_usercreation{'email_rule'}; + } + } elsif (ref($curr_usercreation{'email_rule'}) eq 'HASH') { + foreach my $type (@statuses) { + $curr_rule{$type} = $curr_usercreation{'email_rule'}{$type}; + } + } + push(@{$cancreate{'selfcreate'}},'email'); + push(@contexts,('selfcreateprocessing','emailverified','emailoptions')); + my %curremaildom; + if (ref($curr_usercreation{'cancreate'}{'emaildomain'}) eq 'HASH') { + %curremaildom = %{$curr_usercreation{'cancreate'}{'emaildomain'}}; + } + foreach my $type (@statuses) { + if ($env{'form.cancreate_emailprocess_'.$type} =~ /^(?:approval|automatic)$/) { + $cancreate{'selfcreateprocessing'}{$type} = $env{'form.cancreate_emailprocess_'.$type}; + } + if ($env{'form.cancreate_usernameoptions_'.$type} =~ /^(?:all|first|free)$/) { + $cancreate{'emailverified'}{$type} = $env{'form.cancreate_usernameoptions_'.$type}; + } + if ($env{'form.cancreate_emailoptions_'.$type} =~ /^(any|inst|noninst|custom)$/) { +# +# Retrieve rules (if any) governing types of e-mail address which may be used to verify a username. +# + my $chosen = $1; + if (($chosen eq 'inst') || ($chosen eq 'noninst')) { + my $emaildom; + if ($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})) { + if ($curremaildom{$type}{$chosen} ne $emaildom) { + push(@{$changes{'cancreate'}},'emaildomain'); + } + } elsif ($emaildom ne '') { + push(@{$changes{'cancreate'}},'emaildomain'); + } + } elsif ($emaildom ne '') { + push(@{$changes{'cancreate'}},'emaildomain'); + } + } + $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type}; + } elsif ($chosen eq 'custom') { + my @possemail_rules = &Apache::loncommon::get_env_multiple('form.email_rule_'.$type); + $email_rule{$type} = []; + if (ref($emailrules) eq 'HASH') { + foreach my $rule (@possemail_rules) { + if (exists($emailrules->{$rule})) { + push(@{$email_rule{$type}},$rule); + } + } + } + if (@{$email_rule{$type}}) { + $cancreate{'emailoptions'}{$type} = 'custom'; + if (ref($curr_rule{$type}) eq 'ARRAY') { + if (@{$curr_rule{$type}} > 0) { + foreach my $rule (@{$curr_rule{$type}}) { + if (!grep(/^\Q$rule\E$/,@{$email_rule{$type}})) { + push(@{$changes{'email_rule'}},$type); + } + } + } + foreach my $type (@{$email_rule{$type}}) { + if (!grep(/^\Q$type\E$/,@{$curr_rule{$type}})) { + push(@{$changes{'email_rule'}},$type); + } + } + } else { + push(@{$changes{'email_rule'}},$type); + } + } + } else { + $cancreate{'emailoptions'}{$type} = $env{'form.cancreate_emailoptions_'.$type}; + } + } + } + if (@types) { + if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') { + my @changed = &Apache::loncommon::compare_arrays(\@statuses,$curr_inststatus{'inststatusguest'}); + if (@changed) { + push(@{$changes{'inststatus'}},'inststatusguest'); + } + } else { + push(@{$changes{'inststatus'}},'inststatusguest'); + } + } + } else { + delete($env{'form.cancreate_email'}); + if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') { + if (@{$curr_inststatus{'inststatusguest'}} > 0) { + push(@{$changes{'inststatus'}},'inststatusguest'); + } + } + } + } else { + $save_inststatus{'inststatusguest'} = []; + if (ref($curr_inststatus{'inststatusguest'}) eq 'ARRAY') { + if (@{$curr_inststatus{'inststatusguest'}} > 0) { + push(@{$changes{'inststatus'}},'inststatusguest'); } } } @@ -11242,7 +12047,7 @@ sub modify_selfcreation { } } } - my (@email_rule,%userinfo,%savecaptcha); + my (%userinfo,%savecaptcha); my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info(); # # Populate $cancreate{'emailusername'}{$type} hash ref with information fields (if new user will provide data @@ -11251,8 +12056,8 @@ sub modify_selfcreation { if ($env{'form.cancreate_email'}) { push(@contexts,'emailusername'); - if (ref($types) eq 'ARRAY') { - foreach my $type (@{$types}) { + if (@statuses) { + foreach my $type (@statuses) { if (ref($infofields) eq 'ARRAY') { foreach my $field (@{$infofields}) { if ($env{'form.canmodify_emailusername_'.$type.'_'.$field} =~ /^(required|optional)$/) { @@ -11264,7 +12069,7 @@ sub modify_selfcreation { } # # Populate $cancreate{'notify'} hash ref with names of Domain Coordinators who are to be notified of -# queued requests for self-creation of account using e-mail address as username +# queued requests for self-creation of account verified by e-mail. # my @approvalnotify = &Apache::loncommon::get_env_multiple('form.selfcreationnotifyapproval'); @@ -11284,36 +12089,13 @@ sub modify_selfcreation { push(@{$changes{'cancreate'}},'notify'); } -# -# Retrieve rules (if any) governing types of e-mail address which may be used as a username -# - @email_rule = &Apache::loncommon::get_env_multiple('form.email_rule'); &process_captcha('cancreate',\%changes,\%savecaptcha,$curr_usercreation{'cancreate'}); - if (ref($curr_usercreation{'email_rule'}) eq 'ARRAY') { - if (@{$curr_usercreation{'email_rule'}} > 0) { - foreach my $type (@{$curr_usercreation{'email_rule'}}) { - if (!grep(/^\Q$type\E$/,@email_rule)) { - push(@{$changes{'email_rule'}},$type); - } - } - } - if (@email_rule > 0) { - foreach my $type (@email_rule) { - if (!grep(/^\Q$type\E$/,@{$curr_usercreation{'email_rule'}})) { - push(@{$changes{'email_rule'}},$type); - } - } - } - } elsif (@email_rule > 0) { - push(@{$changes{'email_rule'}},@email_rule); - } } # # Check if domain default is set appropriately, if self-creation of accounts is to be available for # institutional log-in. # if (grep(/^login$/,@{$cancreate{'selfcreate'}})) { - my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); if (!((($domdefaults{'auth_def'} =~/^krb/) && ($domdefaults{'auth_arg_def'} ne '')) || ($domdefaults{'auth_def'} eq 'localauth'))) { $warningmsg = &mt('Although account creation has been set to be available for institutional logins, currently default authentication in this domain has not been set to support this.').' '. @@ -11332,14 +12114,10 @@ sub modify_selfcreation { # which the user may supply, if institutional data is unavailable. # if (($env{'form.cancreate_login'}) || ($env{'form.cancreate_sso'})) { - if (ref($types) eq 'ARRAY') { - if (@{$types} > 1) { - @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate'); - push(@contexts,'statustocreate'); - } else { - undef($cancreate{'statustocreate'}); - } - foreach my $type (@{$types}) { + if (@types) { + @{$cancreate{'statustocreate'}} = &Apache::loncommon::get_env_multiple('form.statustocreate'); + push(@contexts,'statustocreate'); + foreach my $type (@types) { my @modifiable = &Apache::loncommon::get_env_multiple('form.canmodify_'.$type); foreach my $field (@fields) { if (grep(/^\Q$field\E$/,@modifiable)) { @@ -11350,7 +12128,7 @@ sub modify_selfcreation { } } if (ref($curr_usermodify{'selfcreate'}) eq 'HASH') { - foreach my $type (@{$types}) { + foreach my $type (@types) { if (ref($curr_usermodify{'selfcreate'}{$type}) eq 'HASH') { foreach my $field (@fields) { if ($save_usermodify{'selfcreate'}{$type}{$field} ne @@ -11362,7 +12140,7 @@ sub modify_selfcreation { } } } else { - foreach my $type (@{$types}) { + foreach my $type (@types) { push(@{$changes{'selfcreate'}},$type); } } @@ -11411,34 +12189,28 @@ sub modify_selfcreation { } } elsif (ref($curr_usercreation{'cancreate'}{$item}) eq 'HASH') { if (ref($cancreate{$item}) eq 'HASH') { - foreach my $curr (keys(%{$curr_usercreation{'cancreate'}{$item}})) { - if (ref($curr_usercreation{'cancreate'}{$item}{$curr}) eq 'HASH') { - foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$curr}})) { - unless ($curr_usercreation{'cancreate'}{$item}{$curr}{$field} eq $cancreate{$item}{$curr}{$field}) { + foreach my $type (keys(%{$curr_usercreation{'cancreate'}{$item}})) { + if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') { + foreach my $field (keys(%{$curr_usercreation{'cancreate'}{$item}{$type}})) { + unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) { if (!grep(/^$item$/,@{$changes{'cancreate'}})) { push(@{$changes{'cancreate'}},$item); } } } - } elsif ($item eq 'selfcreateprocessing') { - if ($cancreate{$item}{$curr} ne $curr_usercreation{'cancreate'}{$item}{$curr}) { - if (!grep(/^$item$/,@{$changes{'cancreate'}})) { - push(@{$changes{'cancreate'}},$item); - } - } - } else { - if (!$cancreate{$item}{$curr}) { + } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) { + if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) { if (!grep(/^$item$/,@{$changes{'cancreate'}})) { push(@{$changes{'cancreate'}},$item); } } } } - foreach my $field (keys(%{$cancreate{$item}})) { - if (ref($cancreate{$item}{$field}) eq 'HASH') { - foreach my $inner (keys(%{$cancreate{$item}{$field}})) { - if (ref($curr_usercreation{'cancreate'}{$item}{$field}) eq 'HASH') { - unless ($curr_usercreation{'cancreate'}{$item}{$field}{$inner} eq $cancreate{$item}{$field}{$inner}) { + foreach my $type (keys(%{$cancreate{$item}})) { + if (ref($cancreate{$item}{$type}) eq 'HASH') { + foreach my $field (keys(%{$cancreate{$item}{$type}})) { + if (ref($curr_usercreation{'cancreate'}{$item}{$type}) eq 'HASH') { + unless ($curr_usercreation{'cancreate'}{$item}{$type}{$field} eq $cancreate{$item}{$type}{$field}) { if (!grep(/^$item$/,@{$changes{'cancreate'}})) { push(@{$changes{'cancreate'}},$item); } @@ -11449,14 +12221,8 @@ sub modify_selfcreation { } } } - } elsif ($item eq 'selfcreateprocessing') { - if ($cancreate{$item}{$field} ne $curr_usercreation{'cancreate'}{$item}{$field}) { - if (!grep(/^$item$/,@{$changes{'cancreate'}})) { - push(@{$changes{'cancreate'}},$item); - } - } - } else { - if (!$curr_usercreation{'cancreate'}{$item}{$field}) { + } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) { + if ($cancreate{$item}{$type} ne $curr_usercreation{'cancreate'}{$item}{$type}) { if (!grep(/^$item$/,@{$changes{'cancreate'}})) { push(@{$changes{'cancreate'}},$item); } @@ -11471,11 +12237,11 @@ sub modify_selfcreation { push(@{$changes{'cancreate'}},$item); } } - } elsif (ref($cancreate{$item}) eq 'HASH') { - if (!$cancreate{$item}{$curr_usercreation{'cancreate'}{$item}}) { - if (!grep(/^$item$/,@{$changes{'cancreate'}})) { - push(@{$changes{'cancreate'}},$item); - } + } + } elsif (($item eq 'selfcreateprocessing') || ($item eq 'emailverified') || ($item eq 'emailoptions')) { + if (ref($cancreate{$item}) eq 'HASH') { + if (!grep(/^$item$/,@{$changes{'cancreate'}})) { + push(@{$changes{'cancreate'}},$item); } } } elsif ($item eq 'emailusername') { @@ -11508,6 +12274,15 @@ sub modify_selfcreation { if (ref($cancreate{'selfcreateprocessing'}) eq 'HASH') { $save_usercreate{'cancreate'}{'selfcreateprocessing'} = $cancreate{'selfcreateprocessing'}; } + if (ref($cancreate{'emailverified'}) eq 'HASH') { + $save_usercreate{'cancreate'}{'emailverified'} = $cancreate{'emailverified'}; + } + if (ref($cancreate{'emailoptions'}) eq 'HASH') { + $save_usercreate{'cancreate'}{'emailoptions'} = $cancreate{'emailoptions'}; + } + if (ref($cancreate{'emaildomain'}) eq 'HASH') { + $save_usercreate{'cancreate'}{'emaildomain'} = $cancreate{'emaildomain'}; + } if (ref($cancreate{'statustocreate'}) eq 'ARRAY') { $save_usercreate{'cancreate'}{'statustocreate'} = $cancreate{'statustocreate'}; } @@ -11515,16 +12290,18 @@ sub modify_selfcreation { $save_usercreate{'cancreate'}{'shibenv'} = $cancreate{'shibenv'}; } $save_usercreate{'cancreate'}{'emailusername'} = $cancreate{'emailusername'}; - $save_usercreate{'emailrule'} = \@email_rule; + $save_usercreate{'email_rule'} = \%email_rule; my %userconfig_hash = ( usercreation => \%save_usercreate, usermodification => \%save_usermodify, + inststatus => \%save_inststatus, ); + my $putresult = &Apache::lonnet::put_dom('configuration',\%userconfig_hash, $dom); # -# Accumulate details of changes to domain cofiguration for self-creation of usernames in $resulttext +# Accumulate details of changes to domain configuration for self-creation of usernames in $resulttext # if ($putresult eq 'ok') { if (keys(%changes) > 0) { @@ -11532,7 +12309,7 @@ sub modify_selfcreation { if (ref($changes{'cancreate'}) eq 'ARRAY') { my %lt = &selfcreation_types(); foreach my $type (@{$changes{'cancreate'}}) { - my $chgtext; + my $chgtext = ''; if ($type eq 'selfcreate') { if (@{$cancreate{$type}} == 0) { $chgtext .= &mt('Self creation of a new user account is not permitted.'); @@ -11547,18 +12324,25 @@ sub modify_selfcreation { if (grep(/^(login|sso)$/,@{$cancreate{$type}})) { if (ref($cancreate{'statustocreate'}) eq 'ARRAY') { if (@{$cancreate{'statustocreate'}} == 0) { - $chgtext .= '
    '. - ''. - &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts."). - ''; + $chgtext .= ''. + &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts via log-in or single sign-on."). + '
    '; } } } + if (grep(/^email$/,@{$cancreate{$type}})) { + if (!@statuses) { + $chgtext .= ''. + &mt("However, e-mail verification is currently set to 'unavailable' for all user types (including 'other'), so self-creation of accounts is not possible for non-institutional log-in."). + '
    '; + + } + } } } } elsif ($type eq 'shibenv') { if (keys(%{$cancreate{$type}}) == 0) { - $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information'); + $chgtext .= &mt('Shibboleth-autheticated user does not use environment variables to set user information').'
    '; } else { $chgtext .= &mt('Shibboleth-autheticated user information set from environment variables, as follows:'). '
      '; @@ -11571,7 +12355,7 @@ sub modify_selfcreation { } } $chgtext .= '
    '; - } + } } elsif ($type eq 'statustocreate') { if ((ref($cancreate{'selfcreate'}) eq 'ARRAY') && (ref($cancreate{'statustocreate'}) eq 'ARRAY')) { @@ -11584,7 +12368,7 @@ sub modify_selfcreation { &mt("However, no institutional affiliations (including 'other') are currently permitted to create accounts."). ''; } - } elsif (ref($usertypes) eq 'HASH') { + } elsif (keys(%usertypes) > 0) { if (grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) { $chgtext .= &mt('Creation of a new account for an institutional user is restricted to the following institutional affiliation(s):'); } else { @@ -11595,12 +12379,12 @@ sub modify_selfcreation { if ($case eq 'default') { $chgtext .= '
  • '.$othertitle.'
  • '; } else { - $chgtext .= '
  • '.$usertypes->{$case}.'
  • '; + $chgtext .= '
  • '.$usertypes{$case}.'
  • '; } } $chgtext .= ''; if (!grep(/^(login|sso)$/,@{$cancreate{'selfcreate'}})) { - $chgtext .= '
    '. + $chgtext .= ''. &mt('However, users authenticated by institutional login/single sign on are not currently permitted to create accounts.'). ''; } @@ -11612,26 +12396,129 @@ sub modify_selfcreation { $chgtext .= &mt('Although institutional affiliations permitted to create accounts were changed, self creation of accounts is not currently permitted for any authentication types.'); } } + $chgtext .= '
    '; } } elsif ($type eq 'selfcreateprocessing') { my %choices = &Apache::lonlocal::texthash ( automatic => 'Automatic approval', approval => 'Queued for approval', ); - if (@statuses > 1) { - $chgtext .= &mt('Processing of requests to create account with e-mail address as username set as follows:'). - '
      '; - foreach my $type (@statuses) { - if ($type eq 'default') { - $chgtext .= '
    • '.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'
    • '; - } else { - $chgtext .= '
    • '.$usertypes->{$type}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$type}}.'
    • '; - } - } - $chgtext .= '
    '; + if (@types) { + if (@statuses) { + $chgtext .= &mt('Processing of requests to create account with e-mail verification set as follows:'). + '
      '; + foreach my $status (@statuses) { + if ($status eq 'default') { + $chgtext .= '
    • '.$othertitle.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'
    • '; + } else { + $chgtext .= '
    • '.$usertypes{$status}.' -- '.$choices{$cancreate{'selfcreateprocessing'}{$status}}.'
    • '; + } + } + $chgtext .= '
    '; + } + } else { + $chgtext .= &mt('Processing of requests to create account with e-mail verification set to: "[_1]"', + $choices{$cancreate{'selfcreateprocessing'}{'default'}}); + } + } elsif ($type eq 'emailverified') { + my %options = &Apache::lonlocal::texthash ( + all => 'Same as e-mail', + first => 'Omit @domain', + free => 'Free to choose', + ); + if (@types) { + if (@statuses) { + $chgtext .= &mt('For self-created accounts verified by e-mail address, username is set as follows:'). + '
      '; + foreach my $status (@statuses) { + if ($type eq 'default') { + $chgtext .= '
    • '.$othertitle.' -- '.$options{$cancreate{'emailverified'}{$status}}.'
    • '; + } else { + $chgtext .= '
    • '.$usertypes{$status}.' -- '.$options{$cancreate{'emailverified'}{$status}}.'
    • '; + } + } + $chgtext .= '
    '; + } + } else { + $chgtext .= &mt("For self-created accounts verified by e-mail address, user's username is: '[_1]'", + $options{$cancreate{'emailverified'}{'default'}}); + } + } elsif ($type eq 'emailoptions') { + my %options = &Apache::lonlocal::texthash ( + any => 'Any e-mail', + inst => 'Institutional only', + noninst => 'Non-institutional only', + custom => 'Custom restrictions', + ); + if (@types) { + if (@statuses) { + $chgtext .= &mt('For self-created accounts verified by e-mail address, requirements for e-mail address are as follows:'). + '
      '; + foreach my $status (@statuses) { + if ($type eq 'default') { + $chgtext .= '
    • '.$othertitle.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'
    • '; + } else { + $chgtext .= '
    • '.$usertypes{$status}.' -- '.$options{$cancreate{'emailoptions'}{$status}}.'
    • '; + } + } + $chgtext .= '
    '; + } } else { - $chgtext .= &mt('Processing of requests to create account with e-mail address as username set to: "[_1]"', - $choices{$cancreate{'selfcreateprocessing'}{'default'}}); + if ($cancreate{'emailoptions'}{'default'} eq 'any') { + $chgtext .= &mt('For self-created accounts verified by e-mail address, any e-mail may be used'); + } else { + $chgtext .= &mt('For self-created accounts verified by e-mail address, e-mail restricted to: "[_1]"', + $options{$cancreate{'emailoptions'}{'default'}}); + } + } + } elsif ($type eq 'emaildomain') { + my $output; + if (@statuses) { + foreach my $type (@statuses) { + if (ref($cancreate{'emaildomain'}{$type}) eq 'HASH') { + if ($cancreate{'emailoptions'}{$type} eq 'inst') { + if ($type eq 'default') { + if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') || + ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) { + $output = '
  • '.$othertitle.' -- '.&mt('No restriction on e-mail domain').'
  • '; + } else { + $output = '
  • '.$othertitle.' -- '.&mt("User's e-mail address needs to end: [_1]", + $cancreate{'emaildomain'}{$type}{'inst'}).'
  • '; + } + } else { + if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') || + ($cancreate{'emaildomain'}{$type}{'inst'} eq '')) { + $output = '
  • '.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'
  • '; + } else { + $output = '
  • '.$usertypes{$type}.' -- '.&mt("User's e-mail address needs to end: [_1]", + $cancreate{'emaildomain'}{$type}{'inst'}).'
  • '; + } + } + } elsif ($cancreate{'emailoptions'}{$type} eq 'noninst') { + if ($type eq 'default') { + if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') || + ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) { + $output = '
  • '.$othertitle.' -- '.&mt('No restriction on e-mail domain').'
  • '; + } else { + $output = '
  • '.$othertitle.' -- '.&mt("User's e-mail address must not end: [_1]", + $cancreate{'emaildomain'}{$type}{'noninst'}).'
  • '; + } + } else { + if ((ref($cancreate{'emaildomain'}{$type}) ne 'HASH') || + ($cancreate{'emaildomain'}{$type}{'noninst'} eq '')) { + $output = '
  • '.$usertypes{$type}.' -- '.&mt('No restriction on e-mail domain').'
  • '; + } else { + $output = '
  • '.$usertypes{$type}.' -- '.&mt("User's e-mail address must not end: [_1]", + $cancreate{'emaildomain'}{$type}{'noninst'}).'
  • '; + } + } + } + } + } + } + if ($output ne '') { + $chgtext .= &mt('For self-created accounts verified by e-mail address:'). + '
      '.$output.'
    '; } } elsif ($type eq 'captcha') { if ($savecaptcha{$type} eq 'notused') { @@ -11668,11 +12555,11 @@ sub modify_selfcreation { } } elsif ($type eq 'emailusername') { if (ref($cancreate{'emailusername'}) eq 'HASH') { - if (ref($types) eq 'ARRAY') { - foreach my $type (@{$types}) { + if (@statuses) { + foreach my $type (@statuses) { if (ref($cancreate{'emailusername'}{$type}) eq 'HASH') { if (keys(%{$cancreate{'emailusername'}{$type}}) > 0) { - $chgtext .= &mt('When self-creating account with e-mail as username, the following information will be provided by [_1]:',"'$usertypes->{$type}'"). + $chgtext .= &mt('When self-creating account with e-mail verification, the following information will be provided by [_1]:',"'$usertypes{$type}'"). '
      '; foreach my $field (@{$infofields}) { if ($cancreate{'emailusername'}{$type}{$field}) { @@ -11681,48 +12568,86 @@ sub modify_selfcreation { } $chgtext .= '
    '; } else { - $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'
    '; + $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").'
    '; } } else { - $chgtext .= &mt('When self creating account with e-mail as username, no information besides e-mail address will be provided by [_1].',"'$usertypes->{$type}'").'
    '; + $chgtext .= &mt('When self creating account with e-mail verification, no information besides e-mail address will be provided by [_1].',"'$usertypes{$type}'").'
    '; } } } } } elsif ($type eq 'notify') { - $chgtext = &mt('No Domain Coordinators will receive notification of username requests requiring approval.'); + my $numapprove = 0; if (ref($changes{'cancreate'}) eq 'ARRAY') { if ((grep(/^notify$/,@{$changes{'cancreate'}})) && (ref($cancreate{'notify'}) eq 'HASH')) { if ($cancreate{'notify'}{'approval'}) { - $chgtext = &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'}; + $chgtext .= &mt('Notification of username requests requiring approval will be sent to: ').$cancreate{'notify'}{'approval'}; + $numapprove ++; } } } + unless ($numapprove) { + $chgtext .= &mt('No Domain Coordinators will receive notification of username requests requiring approval.'); + } } if ($chgtext) { $resulttext .= '
  • '.$chgtext.'
  • '; } } } - if (ref($changes{'email_rule'}) eq 'ARRAY') { + if ((ref($changes{'email_rule'}) eq 'ARRAY') && (@{$changes{'email_rule'}} > 0)) { my ($emailrules,$emailruleorder) = &Apache::lonnet::inst_userrules($dom,'email'); - my $chgtext = '
      '; - foreach my $type (@email_rule) { - if (ref($emailrules->{$type}) eq 'HASH') { - $chgtext .= '
    • '.$emailrules->{$type}{'name'}.'
    • '; + foreach my $type (@{$changes{'email_rule'}}) { + if (ref($email_rule{$type}) eq 'ARRAY') { + my $chgtext = '
        '; + foreach my $rule (@{$email_rule{$type}}) { + if (ref($emailrules->{$rule}) eq 'HASH') { + $chgtext .= '
      • '.$emailrules->{$rule}{'name'}.'
      • '; + } + } + $chgtext .= '
      '; + my $typename; + if (@types) { + if ($type eq 'default') { + $typename = $othertitle; + } else { + $typename = $usertypes{$type}; + } + $chgtext .= &mt('(Affiliation: [_1])',$typename); + } + if (@{$email_rule{$type}} > 0) { + $resulttext .= '
    • '. + &mt('Accounts may not be created by users verified by e-mail, for e-mail addresses of the following types: ', + $usertypes{$type}). + $chgtext. + '
    • '; + } else { + $resulttext .= '
    • '. + &mt('There are now no restrictions on e-mail addresses which may be used for verification when a user requests an account.'). + '
    • '. + &mt('(Affiliation: [_1])',$typename); + } } } - $chgtext .= '
    '; - if (@email_rule > 0) { - $resulttext .= '
  • '. - &mt('Accounts may not be created by users self-enrolling with e-mail addresses of the following types: '). - $chgtext. - '
  • '; - } else { - $resulttext .= '
  • '. - &mt('There are now no restrictions on e-mail addresses which may be used as a username when self-enrolling.'). - '
  • '; + } + if (ref($changes{'inststatus'}) eq 'ARRAY') { + if (ref($save_inststatus{'inststatusguest'}) eq 'ARRAY') { + if (@{$save_inststatus{'inststatusguest'}} > 0) { + my $chgtext = '
      '; + foreach my $type (@{$save_inststatus{'inststatusguest'}}) { + $chgtext .= '
    • '.$usertypes{$type}.'
    • '; + } + $chgtext .= '
    '; + $resulttext .= '
  • '. + &mt('A user will self-report one of the following affiliations when requesting an account verified by e-mail: '). + $chgtext. + '
  • '; + } else { + $resulttext .= '
  • '. + &mt('No affiliations available for self-reporting when requesting an account verified by e-mail.'). + '
  • '; + } } } if (ref($changes{'selfcreate'}) eq 'ARRAY') { @@ -11730,9 +12655,9 @@ sub modify_selfcreation { my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); foreach my $type (@{$changes{'selfcreate'}}) { my $typename = $type; - if (ref($usertypes) eq 'HASH') { - if ($usertypes->{$type} ne '') { - $typename = $usertypes->{$type}; + if (keys(%usertypes) > 0) { + if ($usertypes{$type} ne '') { + $typename = $usertypes{$type}; } } my @modifiable; @@ -11755,6 +12680,12 @@ sub modify_selfcreation { $resulttext .= ''; } $resulttext .= ''; + my $cachetime = 24*60*60; + $domdefaults{'inststatusguest'} = $save_inststatus{'inststatusguest'}; + &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; + } } else { $resulttext = &mt('No changes made to self-creation settings'); } @@ -12038,9 +12969,16 @@ sub modify_defaults { } my @todelete = &Apache::loncommon::get_env_multiple('form.inststatus_delete'); my @allpos; - my %guests; my %alltypes; - my ($currtitles,$currguests,$currorder); + my @inststatusguest; + if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') { + foreach my $type (@{$currinststatus->{'inststatusguest'}}) { + unless (grep(/^\Q$type\E$/,@todelete)) { + push(@inststatusguest,$type); + } + } + } + my ($currtitles,$currorder); if (ref($currinststatus) eq 'HASH') { if (ref($currinststatus->{'inststatusorder'}) eq 'ARRAY') { foreach my $type (@{$currinststatus->{'inststatusorder'}}) { @@ -12055,14 +12993,8 @@ sub modify_defaults { $allpos[$position] = $type; $alltypes{$type} = $env{'form.inststatus_title_'.$type}; $alltypes{$type} =~ s/`//g; - if ($env{'form.inststatus_guest_'.$type}) { - $guests{$type} = 1; - } } } - if (ref($currinststatus->{'inststatusguest'}) eq 'ARRAY') { - $currguests = join(',',@{$currinststatus->{'inststatusguest'}}); - } $currorder = join(',',@{$currinststatus->{'inststatusorder'}}); $currtitles =~ s/,$//; } @@ -12071,9 +13003,6 @@ sub modify_defaults { my $newtype = $env{'form.addinststatus'}; $newtype =~ s/\W//g; unless (exists($alltypes{$newtype})) { - if ($env{'form.addinststatus_guest'}) { - $guests{$newtype} = 1; - } $alltypes{$newtype} = $env{'form.addinststatus_title'}; $alltypes{$newtype} =~ s/`//g; my $position = $env{'form.addinststatus_pos'}; @@ -12083,13 +13012,10 @@ sub modify_defaults { } } } - my (@orderedstatus,@orderedguests); + my @orderedstatus; foreach my $type (@allpos) { unless (($type eq '') || (grep(/^\Q$type\E$/,@orderedstatus))) { push(@orderedstatus,$type); - if ($guests{$type}) { - push(@orderedguests,$type); - } } } foreach my $type (keys(%alltypes)) { @@ -12100,7 +13026,7 @@ sub modify_defaults { $defaults_hash{'inststatus'} = { inststatustypes => \%alltypes, inststatusorder => \@orderedstatus, - inststatusguest => \@orderedguests, + inststatusguest => \@inststatusguest, }; if (ref($defaults_hash{'inststatus'}) eq 'HASH') { foreach my $item ('inststatustypes','inststatusorder','inststatusguest') { @@ -12110,9 +13036,6 @@ sub modify_defaults { if ($currorder ne join(',',@orderedstatus)) { $changes{'inststatus'}{'inststatusorder'} = 1; } - if ($currguests ne join(',',@orderedguests)) { - $changes{'inststatus'}{'inststatusguest'} = 1; - } my $newtitles; foreach my $item (@orderedstatus) { $newtitles .= $alltypes{$item}.','; @@ -12131,26 +13054,15 @@ sub modify_defaults { foreach my $item (sort(keys(%changes))) { if ($item eq 'inststatus') { if (ref($changes{'inststatus'}) eq 'HASH') { - if (($changes{'inststatus'}{'inststatustypes'}) || $changes{'inststatus'}{'inststatusorder'}) { + if (@orderedstatus) { $resulttext .= '
  • '.&mt('Institutional user status types set to:').' '; foreach my $type (@orderedstatus) { $resulttext .= $alltypes{$type}.', '; } $resulttext =~ s/, $//; $resulttext .= '
  • '; - } - if ($changes{'inststatus'}{'inststatusguest'}) { - $resulttext .= '
  • '; - if (@orderedguests) { - $resulttext .= &mt('Types assignable to "non-institutional" usernames set to:').' '; - foreach my $type (@orderedguests) { - $resulttext .= $alltypes{$type}.', '; - } - $resulttext =~ s/, $//; - } else { - $resulttext .= &mt('Types assignable to "non-institutional" usernames set to none.'); - } - $resulttext .= '
  • '; + } else { + $resulttext .= '
  • '.&mt('Institutional user status types deleted').'
  • '; } } } else { @@ -12978,7 +13890,7 @@ sub modify_helpsettings { order => 'Order', desc => 'Role description', access => 'Role usage', - status => 'Allowed instituional types', + status => 'Allowed institutional types', exc => 'Allowed personnel', inc => 'Disallowed personnel', ); @@ -13077,7 +13989,11 @@ sub modify_coursedefaults { postsubmit => 60, mysqltables => 172800, ); - + my %texoptions = ( + MathJax => 'MathJax', + mimetex => &mt('Convert to Images'), + tth => &mt('TeX to HTML'), + ); $defaultshash{'coursedefaults'} = {}; if (ref($domconfig{'coursedefaults'}) ne 'HASH') { @@ -13137,6 +14053,20 @@ sub modify_coursedefaults { } } } + my $texengine; + if ($env{'form.texengine'} =~ /^(MathJax|mimetex|tth)$/) { + $texengine = $env{'form.texengine'}; + if ($defaultshash{'coursedefaults'}{'texengine'} eq '') { + unless ($texengine eq 'MathJax') { + $changes{'texengine'} = 1; + } + } elsif ($defaultshash{'coursedefaults'}{'texengine'} ne $texengine) { + $changes{'texengine'} = 1; + } + } + if ($texengine ne '') { + $defaultshash{'coursedefaults'}{'texengine'} = $texengine; + } my $currclone = $domconfig{'coursedefaults'}{'canclone'}; my @currclonecode; if (ref($currclone) eq 'HASH') { @@ -13257,8 +14187,8 @@ sub modify_coursedefaults { my %domdefaults = &Apache::lonnet::get_domain_defaults($dom,1); if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) || ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) || - ($changes{'canclone'}) || ($changes{'mysqltables'})) { - foreach my $item ('canuse_pdfforms','uselcmath','usejsme') { + ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'})) { + foreach my $item ('canuse_pdfforms','uselcmath','usejsme','texengine') { if ($changes{$item}) { $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item}; } @@ -13327,6 +14257,11 @@ sub modify_coursedefaults { } else { $resulttext .= '
  • '.&mt('Molecule editor uses JME (Java), if supported by client OS.').'
  • '; } + } elsif ($item eq 'texengine') { + if ($defaultshash{'coursedefaults'}{'texengine'} ne '') { + $resulttext .= '
  • '.&mt('Default method to display mathematics set to: "[_1]"', + $texoptions{$defaultshash{'coursedefaults'}{'texengine'}}).'
  • '; + } } elsif ($item eq 'anonsurvey_threshold') { $resulttext .= '
  • '.&mt('Responder count required for display of anonymous survey submissions set to [_1].',$defaultshash{'coursedefaults'}{'anonsurvey_threshold'}).'
  • '; } elsif ($item eq 'uploadquota') { @@ -13654,12 +14589,12 @@ sub modify_selfenrollment { $resulttext .= ''; } } - if ((exists($changes{'admin'})) || (exists($changes{'default'}))) { - my $cachetime = 24*60*60; - &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); - if (ref($lastactref) eq 'HASH') { - $lastactref->{'domdefaults'} = 1; - } + } + if ((exists($changes{'admin'})) || (exists($changes{'default'}))) { + my $cachetime = 24*60*60; + &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime); + if (ref($lastactref) eq 'HASH') { + $lastactref->{'domdefaults'} = 1; } } $resulttext .= ''; @@ -15233,6 +16168,7 @@ function toggleDisplay(domForm,caller) { var optionsElement = domForm.coursecredits; var checkval = 1; var dispval = 'block'; + var selfcreateRegExp = /^cancreate_emailverified/; if (caller == 'emailoptions') { optionsElement = domForm.cancreate_email; } @@ -15243,6 +16179,11 @@ function toggleDisplay(domForm,caller) { optionsElement = domForm.canclone; checkval = 'instcode'; } + if (selfcreateRegExp.test(caller)) { + optionsElement = domForm.elements[caller]; + checkval = 'other'; + dispval = 'inline' + } if (optionsElement.length) { var currval; for (var i=0; i
    '.&mt($type).'
    '. + $datatable .= '
    '.&mt($type).'
    '. '
    '. + ''. '

    '; if ($lonhost eq '') { $datatable .= ''; @@ -5224,7 +5433,7 @@ sub print_loadbalancing { $homedom_div_style = 'display: block'; } } - $datatable .= '

    '. + $datatable .= '

    '. '
    '.$disabledtext.'
    '."\n". '
    '.&mt('Offloads to:').'
    '; @@ -5388,9 +5597,14 @@ sub loadbalancing_titles { '_LC_ipchange' => &mt('Non-SSO users with IP mismatch'), ); my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external','_LC_ipchangesso','_LC_ipchange'); + my @available; if (ref($types) eq 'ARRAY') { - unshift(@alltypes,@{$types},'default'); + @available = @{$types}; } + unless (grep(/^default$/,@available)) { + push(@available,'default'); + } + unshift(@alltypes,@available); my %titles; foreach my $type (@alltypes) { if ($type =~ /^_LC_/) { @@ -5431,10 +5645,10 @@ sub loadbalance_rule_row { } my $space; if ($islast && $num == 1) { - $space = '
     
    '; + $space = '
     
    '; } my $output = - '
    '.$space. + '
    '.$space. '
    '.$title.'
    '.$space. '
    '."\n"; @@ -5517,8 +5731,8 @@ 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', @@ -5671,7 +5885,7 @@ sub print_usercreation { } $datatable .= ''. '
    '.$lt{$item}. - ''; + ''; my @options = ('any'); if (ref($rules) eq 'HASH') { if (keys(%{$rules}) > 0) { @@ -5745,7 +5959,8 @@ sub print_usercreation { sub print_selfcreation { my ($position,$dom,$settings,$rowtotal) = @_; - my (@selfcreate,$createsettings,$processing,$datatable); + my (@selfcreate,$createsettings,$processing,$emailoptions,$emailverified, + $emaildomain,$datatable); if (ref($settings) eq 'HASH') { if (ref($settings->{'cancreate'}) eq 'HASH') { $createsettings = $settings->{'cancreate'}; @@ -5762,12 +5977,22 @@ sub print_selfcreation { if (ref($createsettings->{'selfcreateprocessing'}) eq 'HASH') { $processing = $createsettings->{'selfcreateprocessing'}; } + if (ref($createsettings->{'emailoptions'}) eq 'HASH') { + $emailoptions = $createsettings->{'emailoptions'}; + } + if (ref($createsettings->{'emailverified'}) eq 'HASH') { + $emailverified = $createsettings->{'emailverified'}; + } + if (ref($createsettings->{'emaildomain'}) eq 'HASH') { + $emaildomain = $createsettings->{'emaildomain'}; + } } } } my %radiohash; my $numinrow = 4; map { $radiohash{'cancreate_'.$_} = 1; } @selfcreate; + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); if ($position eq 'top') { my %choices = &Apache::lonlocal::texthash ( cancreate_login => 'Institutional Login', @@ -5783,13 +6008,11 @@ sub print_selfcreation { \%choices,$itemcount,$onclick); $$rowtotal += $itemcount; - my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - if (ref($usertypes) eq 'HASH') { if (keys(%{$usertypes}) > 0) { $datatable .= &insttypes_row($createsettings,$types,$usertypes, $dom,$numinrow,$othertitle, - 'statustocreate',$$rowtotal); + 'statustocreate',$rowtotal); $$rowtotal ++; } } @@ -5834,142 +6057,418 @@ sub print_selfcreation { $$rowtotal ++; } elsif ($position eq 'middle') { my %domconf = &Apache::lonnet::get_dom('configuration',['usermodification'],$dom); - my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); - $usertypes->{'default'} = $othertitle; + my @posstypes; if (ref($types) eq 'ARRAY') { - push(@{$types},'default'); - $usertypes->{'default'} = $othertitle; - foreach my $status (@{$types}) { - $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'}, - $numinrow,$$rowtotal,$usertypes); - $$rowtotal ++; - } + @posstypes = @{$types}; + } + unless (grep(/^default$/,@posstypes)) { + push(@posstypes,'default'); + } + my %usertypeshash; + if (ref($usertypes) eq 'HASH') { + %usertypeshash = %{$usertypes}; + } + $usertypeshash{'default'} = $othertitle; + foreach my $status (@posstypes) { + $datatable .= &modifiable_userdata_row('selfcreate',$status,$domconf{'usermodification'}, + $numinrow,$$rowtotal,\%usertypeshash); + $$rowtotal ++; } } else { my %choices = &Apache::lonlocal::texthash ( - cancreate_email => 'E-mail address as username', + 'cancreate_email' => 'Non-institutional username (via e-mail verification)', ); my @toggles = sort(keys(%choices)); my %defaultchecked = ( 'cancreate_email' => 'off', ); - my $itemcount = 0; + my $customclass = 'LC_selfcreate_email'; + my $classprefix = 'LC_canmodify_emailusername_'; + my $optionsprefix = 'LC_options_emailusername_'; my $display = 'none'; + my $rowstyle = 'display:none'; if (grep(/^\Qemail\E$/,@selfcreate)) { $display = 'block'; + $rowstyle = 'display:table-row'; } - my $onclick = "toggleDisplay(this.form,'emailoptions');"; - my $additional = '
    '; + my $onclick = "toggleRows(this.form,'cancreate_email','selfassign','$customclass','$classprefix','$optionsprefix');"; + ($datatable,$$rowtotal) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked, + \%choices,$$rowtotal,$onclick); + $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal,$customclass, + $rowstyle); + $$rowtotal ++; + $datatable .= &captcha_choice('cancreate',$createsettings,$$rowtotal,$customclass, + $rowstyle); + $$rowtotal ++; + my (@ordered,@posstypes,%usertypeshash); my %domdefaults = &Apache::lonnet::get_domain_defaults($dom); - my $usertypes = {}; - my $order = []; - if ((ref($domdefaults{'inststatustypes'}) eq 'HASH') && (ref($domdefaults{'inststatusguest'}) eq 'ARRAY')) { - $usertypes = $domdefaults{'inststatustypes'}; - $order = $domdefaults{'inststatusguest'}; - } - if (ref($order) eq 'ARRAY') { - push(@{$order},'default'); - if (@{$order} > 1) { - $usertypes->{'default'} = &mt('Other users'); - $additional .= ''; - foreach my $status (@{$order}) { - $additional .= ''; - } - $additional .= ''; - foreach my $status (@{$order}) { - $additional .= ''; + my ($emailrules,$emailruleorder) = + &Apache::lonnet::inst_userrules($dom,'email'); + my $primary_id = &Apache::lonnet::domain($dom,'primary'); + my $intdom = &Apache::lonnet::internet_dom($primary_id); + if (ref($types) eq 'ARRAY') { + @posstypes = @{$types}; + } + if (@posstypes) { + unless (grep(/^default$/,@posstypes)) { + push(@posstypes,'default'); + } + if (ref($usertypes) eq 'HASH') { + %usertypeshash = %{$usertypes}; + } + my $currassign; + if (ref($domdefaults{'inststatusguest'}) eq 'ARRAY') { + $currassign = { + selfassign => $domdefaults{'inststatusguest'}, + }; + @ordered = @{$domdefaults{'inststatusguest'}}; + } else { + $currassign = { selfassign => [] }; + } + my $onclicktypes = "toggleDataRow(this.form,'selfassign','$customclass','$optionsprefix',);". + "toggleDataRow(this.form,'selfassign','$customclass','$classprefix',1);"; + $datatable .= &insttypes_row($currassign,$types,$usertypes,$dom, + $numinrow,$othertitle,'selfassign', + $rowtotal,$onclicktypes,$customclass, + $rowstyle); + $$rowtotal ++; + $usertypeshash{'default'} = $othertitle; + foreach my $status (@posstypes) { + my $css_class; + if ($$rowtotal%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$/,@ordered)) { + $currstyle = $rowstyle; + $hidden = 0; + } + $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain, + $emailrules,$emailruleorder,$settings,$status,$rowid, + $usertypeshash{$status},$css_class,$currstyle,$intdom); + unless ($hidden) { + $$rowtotal ++; } - $additional .= '
    '.$usertypes->{$status}.'
    '.&email_as_username($rowtotal,$processing,$status).'
    '; - } else { - $usertypes->{'default'} = &mt('All users'); - $additional .= &email_as_username($rowtotal,$processing); } + } else { + my $css_class; + if ($$rowtotal%2) { + $css_class = 'LC_odd_row '; + } + $css_class .= $customclass; + $usertypeshash{'default'} = $othertitle; + $datatable .= &noninst_users($processing,$emailverified,$emailoptions,$emaildomain, + $emailrules,$emailruleorder,$settings,'default','', + $othertitle,$css_class,$rowstyle,$intdom); + $$rowtotal ++; } - $additional .= '
    '."\n"; - - ($datatable,$itemcount) = &radiobutton_prefs(\%radiohash,\@toggles,\%defaultchecked, - \%choices,$$rowtotal,$onclick,$additional); - $$rowtotal ++; - $datatable .= &print_requestmail($dom,'selfcreation',$createsettings,$rowtotal); - $$rowtotal ++; my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info(); $numinrow = 1; - if (ref($order) eq 'ARRAY') { - foreach my $status (@{$order}) { + if (@posstypes) { + foreach my $status (@posstypes) { + my $rowid = $classprefix.$status; + my $datarowstyle = 'display:none'; + if (grep(/^\Q$status\E$/,@ordered)) { + $datarowstyle = $rowstyle; + } $datatable .= &modifiable_userdata_row('cancreate','emailusername_'.$status,$settings, - $numinrow,$$rowtotal,$usertypes,$infofields,$infotitles); - $$rowtotal ++; + $numinrow,$$rowtotal,\%usertypeshash,$infofields, + $infotitles,$rowid,$customclass,$datarowstyle); + unless ($datarowstyle eq 'display:none') { + $$rowtotal ++; + } } + } else { + $datatable .= &modifiable_userdata_row('cancreate','emailusername_default',$settings, + $numinrow,$$rowtotal,\%usertypeshash,$infofields, + $infotitles,'',$customclass,$rowstyle); } - my ($emailrules,$emailruleorder) = - &Apache::lonnet::inst_userrules($dom,'email'); - if (ref($emailrules) eq 'HASH') { - if (keys(%{$emailrules}) > 0) { - $datatable .= &user_formats_row('email',$settings,$emailrules, - $emailruleorder,$numinrow,$$rowtotal); - $$rowtotal ++; + } + return $datatable; +} + +sub selfcreate_javascript { + return <<"ENDSCRIPT"; + + + +ENDSCRIPT +} + +sub noninst_users { + my ($processing,$emailverified,$emailoptions,$emaildomain,$emailrules, + $emailruleorder,$settings,$type,$rowid,$typetitle,$css_class,$rowstyle,$intdom) = @_; + 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); + if ($type eq 'default') { + $description = &mt('Requests for: [_1]',$typetitle); + } else { + $description = &mt('Requests for: [_1] (status self-reported)',$typetitle); + } + $output = ''. + "
    $description'. + ''; + my %headers = &Apache::lonlocal::texthash( + approve => 'Processing', + email => 'E-mail', + username => 'Username', + ); + foreach my $item ('approve','email','username') { + $output .= ''; + } + $output .= ''; + foreach my $item ('approve','email','username') { + $output .= ''."\n"; } - $$rowtotal ++; + $output .= "
    '.$headers{$item}.'
    '; + my (%choices,@options,$hashref,$defoption,$name,$onclick,$hascustom); + if ($item eq 'approve') { + %choices = &Apache::lonlocal::texthash ( + automatic => 'Automatically approved', + approval => 'Queued for approval', + ); + @options = ('automatic','approval'); + $hashref = $processing; + $defoption = 'automatic'; + $name = 'cancreate_emailprocess_'.$type; + } elsif ($item eq 'email') { + %choices = &Apache::lonlocal::texthash ( + any => 'Any e-mail', + inst => 'Institutional only', + noninst => 'Non-institutional only', + custom => 'Custom restrictions', + ); + @options = ('any','inst','noninst'); + my $showcustom; + if (ref($emailrules) eq 'HASH') { + if (keys(%{$emailrules}) > 0) { + push(@options,'custom'); + $showcustom = 'cancreate_emailrule'; + if (ref($settings) eq 'HASH') { + if (ref($settings->{'email_rule'}) eq 'ARRAY') { + foreach my $rule (@{$settings->{'email_rule'}}) { + if (exists($emailrules->{$rule})) { + $hascustom ++; + } + } + } elsif (ref($settings->{'email_rule'}) eq 'HASH') { + if (ref($settings->{'email_rule'}{$type}) eq 'ARRAY') { + foreach my $rule (@{$settings->{'email_rule'}{$type}}) { + if (exists($emailrules->{$rule})) { + $hascustom ++; + } + } + } + } + } + } + } + $onclick = ' onclick="toggleEmailOptions(this.form,'."'cancreate_emailoptions','$showcustom',". + "'cancreate_emaildomain','$type'".');"'; + $hashref = $emailoptions; + $defoption = 'any'; + $name = 'cancreate_emailoptions_'.$type; + } elsif ($item eq 'username') { + %choices = &Apache::lonlocal::texthash ( + all => 'Same as e-mail', + first => 'Omit @domain', + free => 'Free to choose', + ); + @options = ('all','first','free'); + $hashref = $emailverified; + $defoption = 'all'; + $name = 'cancreate_usernameoptions_'.$type; + } + foreach my $option (@options) { + my $checked; + if (ref($hashref) eq 'HASH') { + if ($type eq '') { + if (!exists($hashref->{'default'})) { + if ($option eq $defoption) { + $checked = ' checked="checked"'; + } + } else { + if ($hashref->{'default'} eq $option) { + $checked = ' checked="checked"'; + } } } else { - if ($processing->{$type} eq $option) { - $checked = ' checked="checked"'; + if (!exists($hashref->{$type})) { + if ($option eq $defoption) { + $checked = ' checked="checked"'; + } + } else { + if ($hashref->{$type} eq $option) { + $checked = ' checked="checked"'; + } } } + } elsif (($item eq 'email') && ($hascustom)) { + if ($option eq 'custom') { + $checked = ' checked="checked"'; + } + } elsif ($option eq $defoption) { + $checked = ' checked="checked"'; + } + $output .= '
    '; + if ($item eq 'email') { + if ($option eq 'custom') { + my $id = 'cancreate_emailrule_'.$type; + my $display = 'none'; + if ($checked) { + $display = 'inline'; + } + my $numinrow = 2; + $output .= '
    '. + ''.&mt('Disallow').''. + &user_formats_row('email',$settings,$emailrules, + $emailruleorder,$numinrow,'',$type); + '
    '; + } elsif (($option eq 'inst') || ($option eq 'noninst')) { + my %text = &Apache::lonlocal::texthash ( + inst => 'must end:', + noninst => 'cannot end:', + ); + my $value; + if (ref($emaildomain) eq 'HASH') { + if (ref($emaildomain->{$type}) eq 'HASH') { + $value = $emaildomain->{$type}->{$option}; + } + } + if ($value eq '') { + $value = '@'.$intdom; + } + my $condition = 'cancreate_emaildomain_'.$option.'_'.$type; + my $display = 'none'; + if ($checked) { + $display = 'inline'; + } + $output .= '
    '. + ''.$text{$option}.' '. + ''. + '
    '; + } } - } elsif ($option eq 'automatic') { - $checked = ' checked="checked"'; - } - my $name = 'cancreate_emailprocess'; - if (($type ne '') && ($type ne 'default')) { - $name .= '_'.$type; - } - $output .= ''; - if ($type eq '') { - $output .= ' '; - } else { - $output .= '
    '; } + $output .= '
    '.$rowname.''."\n". ''."\n". - ''. - ''. + ''; + } return $output; } @@ -6311,17 +6835,12 @@ sub print_defaults { } else { my %defaults; if (ref($settings) eq 'HASH') { - if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH') && - (ref($settings->{'inststatusguest'}) eq 'ARRAY')) { + if ((ref($settings->{'inststatusorder'}) eq 'ARRAY') && (ref($settings->{'inststatustypes'}) eq 'HASH')) { my $maxnum = @{$settings->{'inststatusorder'}}; for (my $i=0; $i<$maxnum; $i++) { $css_class = $rownum%2?' class="LC_odd_row"':''; my $item = $settings->{'inststatusorder'}->[$i]; my $title = $settings->{'inststatustypes'}->{$item}; - my $guestok; - if (grep(/^\Q$item\E$/,@{$settings->{'inststatusguest'}})) { - $guestok = 1; - } my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'$item'".');"'; $datatable .= ''. ''. - ''. - ''; + ''; } $css_class = $rownum%2?' class="LC_odd_row"':''; my $chgstr = ' onchange="javascript:reorderTypes(this.form,'."'addinststatus_pos'".');"'; @@ -6367,14 +6875,9 @@ sub print_defaults { $datatable .= ' '.&mt('Internal ID:'). ''. ' '.&mt('(new)'). - ''. - ''; ''."\n"; $rownum ++; } @@ -6537,7 +7040,7 @@ sub print_scantronformat { } $datatable .= ''; if (keys(%error) == 0) { - $datatable .= ''. + my $css_class; + if ($rowcount%2) { + $css_class = 'LC_odd_row'; + } + if ($customcss) { + $css_class .= " $customcss"; + } + $css_class =~ s/^\s+//; + if ($css_class) { + $css_class = ' class="'.$css_class.'"'; + } + if ($rowstyle) { + $css_class .= ' style="'.$rowstyle.'"'; + } + if ($rowid) { + $rowid = ' id="'.$rowid.'"'; + } + $output = ''. ''. ''; + $output .= '
    '."\n"; @@ -6021,7 +6533,7 @@ sub captcha_choice { # specified for use with the key should be broad enough to accommodate all servers in the LON-CAPA domain. # $output .= '
    '."\n". + '
    '."\n". ''.$pubtext.' '."\n". '
    '."\n". @@ -6037,23 +6549,19 @@ sub captcha_choice { } sub user_formats_row { - my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount) = @_; + my ($type,$settings,$rules,$ruleorder,$numinrow,$rowcount,$status) = @_; my $output; my %text = ( 'username' => 'new usernames', 'id' => 'IDs', - 'email' => 'self-created accounts (e-mail)', ); - my $css_class = $rowcount%2?' class="LC_odd_row"':''; - $output = '
    '; - if ($type eq 'email') { - $output .= &mt("Formats disallowed for $text{$type}: "); - } else { - $output .= &mt("Format rules to check for $text{$type}: "); + unless ($type eq 'email') { + my $css_class = $rowcount%2?' class="LC_odd_row"':''; + $output = '
    '. + &mt("Format rules to check for $text{$type}: "). + ''; } - $output .= ''. - ''; + $output .= '
    '; my $rem; if (ref($ruleorder) eq 'ARRAY') { for (my $i=0; $i<@{$ruleorder}; $i++) { @@ -6071,25 +6579,41 @@ sub user_formats_row { if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}})) { $check = ' checked="checked" '; } + } elsif ((ref($settings->{$type.'_rule'}) eq 'HASH') && ($status ne '')) { + if (ref($settings->{$type.'_rule'}->{$status}) eq 'ARRAY') { + if (grep(/^\Q$ruleorder->[$i]\E$/,@{$settings->{$type.'_rule'}->{$status}})) { + $check = ' checked="checked" '; + } + } } } + my $name = $type.'_rule'; + if ($type eq 'email') { + $name .= '_'.$status; + } $output .= ''; } } $rem = @{$ruleorder}%($numinrow); } - my $colsleft = $numinrow - $rem; + my $colsleft; + if ($rem) { + $colsleft = $numinrow - $rem; + } if ($colsleft > 1 ) { $output .= ''; } elsif ($colsleft == 1) { $output .= ''; } - $output .= '
    '. ''. '  
    '; + unless ($type eq 'email') { + $output .= '
    '. @@ -6334,23 +6853,12 @@ sub print_defaults { } $datatable .= ''; } - my ($checkedon,$checkedoff); - $checkedoff = ' checked="checked"'; - if ($guestok) { - $checkedon = $checkedoff; - $checkedoff = ''; - } $datatable .= ' '.&mt('Internal ID:').' '.$item.' '. ''. &mt('delete').''.&mt('Name displayed:'). + ''.&mt('Name displayed:'). ''. - ''. - ''.(' 'x2). - '
    '. + ''. &mt('Name displayed:'). ''. - ''.(' 'x2). - '
    '; + $datatable .= ''; if (!$switchserver) { $datatable .= &mt('Upload:').'
    '; } @@ -7272,13 +7775,14 @@ sub build_category_rows { } sub modifiable_userdata_row { - my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref) = @_; + my ($context,$item,$settings,$numinrow,$rowcount,$usertypes,$fieldsref,$titlesref, + $rowid,$customcss,$rowstyle) = @_; my ($role,$rolename,$statustype); $role = $item; if ($context eq 'cancreate') { - if ($item =~ /^emailusername_(.+)$/) { - $statustype = $1; - $role = 'emailusername'; + if ($item =~ /^(emailusername)_(.+)$/) { + $role = $1; + $statustype = $2; if (ref($usertypes) eq 'HASH') { if ($usertypes->{$statustype}) { $rolename = &mt('Data provided by [_1]',$usertypes->{$statustype}); @@ -7313,8 +7817,24 @@ sub modifiable_userdata_row { %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); } my $output; - my $css_class = $rowcount%2?' class="LC_odd_row"':''; - $output = '
    '.$rolename.''; my $rem; @@ -7348,9 +7868,10 @@ sub modifiable_userdata_row { } } } - - for (my $i=0; $i<@fields; $i++) { - my $rem = $i%($numinrow); + + my $total = scalar(@fields); + for (my $i=0; $i<$total; $i++) { + $rem = $i%($numinrow); if ($rem == 0) { if ($i > 0) { $output .= ''; @@ -7392,10 +7913,13 @@ sub modifiable_userdata_row { ''; } $output .= ''; - $rem = @fields%($numinrow); } - my $colsleft = $numinrow - $rem; - if ($colsleft > 1 ) { + $rem = $total%$numinrow; + my $colsleft; + if ($rem) { + $colsleft = $numinrow - $rem; + } + if ($colsleft > 1) { $output .= ''; } elsif ($colsleft == 1) { @@ -7406,11 +7930,14 @@ sub modifiable_userdata_row { } sub insttypes_row { - my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rownum) = @_; + my ($settings,$types,$usertypes,$dom,$numinrow,$othertitle,$context,$rowtotal,$onclick, + $customcss,$rowstyle) = @_; my %lt = &Apache::lonlocal::texthash ( cansearch => 'Users allowed to search', 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') { @@ -7420,9 +7947,22 @@ sub insttypes_row { if ($context eq 'statustocreate') { $class = 'LC_right_item'; } - my $css_class = ' class="LC_odd_row"'; - if ($rownum ne '') { - $css_class = ($rownum%2? ' class="LC_odd_row"':''); + my $css_class; + if ($$rowtotal%2) { + $css_class = 'LC_odd_row'; + } + if ($customcss) { + $css_class .= ' '.$customcss; + } + $css_class =~ s/^\s+//; + if ($css_class) { + $css_class = ' class="'.$css_class.'"'; + } + if ($rowstyle) { + $css_class .= ' style="'.$rowstyle.'"'; + } + if ($onclick) { + $onclick = 'onclick="'.$onclick.'" '; } my $output = ''. ''; } } $rem = @{$types}%($numinrow); } my $colsleft = $numinrow - $rem; - if (($rem == 0) && (@{$types} > 0)) { - $output .= ''; - } - if ($colsleft > 1) { - $output .= ''; + } + if ($colsleft > 1) { + $output .= ''. - '
    '. ' '.$lt{$context}.$showdom. @@ -7444,6 +7984,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" '; } @@ -7451,36 +7995,45 @@ sub insttypes_row { $output .= ''. '
    '; + if ($context eq 'overrides') { + if ($colsleft > 1) { + $output .= ''; + } else { + $output .= ''; + } + $output .= ' '; } else { - $output .= ''; - } - my $defcheck = ' '; - if (ref($settings) eq 'HASH') { - if (ref($settings->{$context}) eq 'ARRAY') { - if (grep(/^default$/,@{$settings->{$context}})) { + if (($rem == 0) && (@{$types} > 0)) { + $output .= '
    '; + } else { + $output .= ''; + } + 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 .= ''; } - $output .= '