--- loncom/interface/loncreateuser.pm 2009/05/23 12:37:51 1.295.2.2 +++ loncom/interface/loncreateuser.pm 2023/11/04 00:06:00 1.472 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Create a user # -# $Id: loncreateuser.pm,v 1.295.2.2 2009/05/23 12:37:51 raeburn Exp $ +# $Id: loncreateuser.pm,v 1.472 2023/11/04 00:06:00 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -51,13 +51,14 @@ In LON-CAPA, roles are actually collecti Assistant", "Course Coordinator", and other such roles are really just collection of privileges that are useful in many circumstances. -Creating custom roles can be done by the Domain Coordinator through -the Create User functionality. That screen will show all privileges -that can be assigned to users. For a complete list of privileges, -please see C. +Custom roles can be defined by a Domain Coordinator, Course Coordinator +or Community Coordinator via the Manage User functionality. +The custom role editor screen will show all privileges which can be +assigned to users. For a complete list of privileges, please see +C. -Custom role definitions are stored in the C file of the role -author. +Custom role definitions are stored in the C file of the creator +of the role. =cut @@ -68,8 +69,10 @@ use Apache::loncommon; use Apache::lonlocal; use Apache::longroup; use Apache::lonuserutils; -use Apache::selfenroll(); +use Apache::loncoursequeueadmin; +use Apache::lonviewcoauthors; use LONCAPA qw(:DEFAULT :match); +use HTML::Entities; my $loginscript; # piece of javascript used in two separate instances my $authformnop; @@ -77,9 +80,10 @@ my $authformkrb; my $authformint; my $authformfsys; my $authformloc; +my $authformlti; sub initialize_authen_forms { - my ($dom,$formname,$curr_authtype,$mode) = @_; + my ($dom,$formname,$curr_authtype,$mode,$readonly) = @_; my ($krbdef,$krbdefdom) = &Apache::loncommon::get_kerberos_defaults($dom); my %param = ( formname => $formname, kerb_def_dom => $krbdefdom, @@ -87,7 +91,7 @@ sub initialize_authen_forms { domain => $dom, ); my %abv_auth = &auth_abbrev(); - if ($curr_authtype =~ /^(krb4|krb5|internal|localauth|unix):(.*)$/) { + if ($curr_authtype =~ /^(krb4|krb5|internal|localauth|unix|lti):(.*)$/) { my $long_auth = $1; my $curr_autharg = $2; my %abv_auth = &auth_abbrev(); @@ -100,192 +104,769 @@ sub initialize_authen_forms { $param{'mode'} = $mode; } } + if ($readonly) { + $param{'readonly'} = 1; + } $loginscript = &Apache::loncommon::authform_header(%param); $authformkrb = &Apache::loncommon::authform_kerberos(%param); $authformnop = &Apache::loncommon::authform_nochange(%param); $authformint = &Apache::loncommon::authform_internal(%param); $authformfsys = &Apache::loncommon::authform_filesystem(%param); $authformloc = &Apache::loncommon::authform_local(%param); + $authformlti = &Apache::loncommon::authform_lti(%param); } sub auth_abbrev { my %abv_auth = ( - krb4 => 'krb', - internal => 'int', - localuth => 'loc', - unix => 'fsys', + krb5 => 'krb', + krb4 => 'krb', + internal => 'int', + localauth => 'loc', + unix => 'fsys', + lti => 'lti', ); return %abv_auth; } # ==================================================== -sub portfolio_quota { - my ($ccuname,$ccdomain) = @_; +sub user_quotas { + my ($ccuname,$ccdomain,$name) = @_; my %lt = &Apache::lonlocal::texthash( - 'usrt' => "User Tools", - 'disk' => "Disk space allocated to user's portfolio files", - 'cuqu' => "Current quota", 'cust' => "Custom quota", - 'defa' => "Default", 'chqu' => "Change quota", ); - my ($currquota,$quotatype,$inststatus,$defquota) = - &Apache::loncommon::get_user_quota($ccuname,$ccdomain); + my ($output,$longinsttype); my ($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($ccdomain); - my ($longinsttype,$showquota,$custom_on,$custom_off,$defaultinfo); - if ($inststatus ne '') { - if ($usertypes->{$inststatus} ne '') { - $longinsttype = $usertypes->{$inststatus}; + my %titles = &Apache::lonlocal::texthash ( + portfolio => "Disk space allocated to user's portfolio files", + author => "Disk space allocated to user's Authoring Space", + ); + my ($currquota,$quotatype,$inststatus,$defquota) = + &Apache::loncommon::get_user_quota($ccuname,$ccdomain,$name); + if ($longinsttype eq '') { + if ($inststatus ne '') { + if ($usertypes->{$inststatus} ne '') { + $longinsttype = $usertypes->{$inststatus}; + } } } + my ($showquota,$custom_on,$custom_off,$defaultinfo,$colspan); $custom_on = ' '; $custom_off = ' checked="checked" '; - my $quota_javascript = <<"END_SCRIPT"; - -END_SCRIPT + $colspan = ' colspan="2"'; if ($quotatype eq 'custom') { $custom_on = $custom_off; $custom_off = ' '; $showquota = $currquota; if ($longinsttype eq '') { $defaultinfo = &mt('For this user, the default quota would be [_1]' - .' Mb.',$defquota); + .' MB.',$defquota); } else { $defaultinfo = &mt("For this user, the default quota would be [_1]". - " Mb, as determined by the user's institutional". - " affiliation ([_2]).",$defquota,$longinsttype); + " MB,[_2]as determined by the user's institutional". + " affiliation ([_3]).",$defquota,'
',$longinsttype); } } else { if ($longinsttype eq '') { $defaultinfo = &mt('For this user, the default quota is [_1]' - .' Mb.',$defquota); + .' MB.',$defquota); } else { $defaultinfo = &mt("For this user, the default quota of [_1]". - " Mb, is determined by the user's institutional". - " affiliation ([_2]).",$defquota,$longinsttype); + " MB,[_2]is determined by the user's institutional". + " affiliation ([_3]).",$defquota,'
'.$longinsttype); } } - my $output = $quota_javascript."\n". - '

'.$lt{'usrt'}.'

'."\n". - &Apache::loncommon::start_data_table(); - - if (&Apache::lonnet::allowed('mut',$ccdomain)) { - $output .= &build_tools_display($ccuname,$ccdomain,'tools'); - } if (&Apache::lonnet::allowed('mpq',$ccdomain)) { $output .= ''."\n". - ' '.$lt{'disk'}.''."\n". + ' '.$titles{$name}.''."\n". ' '."\n". &Apache::loncommon::start_data_table_row()."\n". - ' '.$lt{'cuqu'}.': '. - $currquota.' Mb.  '. + ' '. + &mt('Current quota: [_1] MB',$currquota).'  '. $defaultinfo.''."\n". &Apache::loncommon::end_data_table_row()."\n". &Apache::loncommon::start_data_table_row()."\n". - ' '.$lt{'chqu'}. + ''.$lt{'chqu'}. ':  '. - '  '. - ' Mb'."\n". + ''. + &mt('Default ([_1] MB)',$defquota).' '. + '  '. + ' '.&mt('MB').''."\n". &Apache::loncommon::end_data_table_row()."\n"; - } - $output .= &Apache::loncommon::end_data_table(); + } return $output; } +sub user_quota_js { + return <<"END_SCRIPT"; + +END_SCRIPT + +} + +sub set_custom_js { + return <<"END_SCRIPT"; + + + +END_SCRIPT + +} + sub build_tools_display { my ($ccuname,$ccdomain,$context) = @_; - my (@usertools,%userenv,$output); + my (@usertools,%userenv,$output,@options,%validations,%reqtitles,%reqdisplay, + $colspan,$isadv,%domconfig,@defaulteditors,@customeditors,@custommanagers, + @possmanagers,$editorsty,$customsty); my %lt = &Apache::lonlocal::texthash ( 'blog' => "Personal User Blog", 'aboutme' => "Personal Information Page", + 'webdav' => "WebDAV access to Authoring Spaces (https)", + 'editors' => "Available Editors", + 'managers' => "Co-authors who can add/revoke co-authors", 'portfolio' => "Personal User Portfolio", + 'portaccess' => "Portfolio Shareable", + 'timezone' => "Can set Time Zone", 'avai' => "Available", 'cusa' => "availability", 'chse' => "Change setting", 'usde' => "Use default", 'uscu' => "Use custom", 'official' => 'Can request creation of official courses', - 'unofficial' => 'Can request creation of unofficial courses', + 'unofficial' => 'Can request creation of unofficial courses', + 'community' => 'Can request creation of communities', + 'textbook' => 'Can request creation of textbook courses', + 'placement' => 'Can request creation of placement tests', + 'lti' => 'Can request creation of LTI courses', + 'requestauthor' => 'Can request author space', + 'edit' => 'Standard editor (Edit)', + 'xml' => 'Text editor (EditXML)', + 'daxe' => 'Daxe editor (Daxe)', ); + $isadv = &Apache::lonnet::is_advanced_user($ccdomain,$ccuname); if ($context eq 'requestcourses') { %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname, - 'requestcourses.official','requestcourses.unofficial'); - @usertools = ('official','unofficial'); + 'requestcourses.official','requestcourses.unofficial', + 'requestcourses.community','requestcourses.textbook', + 'requestcourses.placement','requestcourses.lti'); + @usertools = ('official','unofficial','community','textbook','placement','lti'); + @options =('norequest','approval','autolimit','validate'); + %validations = &Apache::lonnet::auto_courserequest_checks($ccdomain); + %reqtitles = &courserequest_titles(); + %reqdisplay = &courserequest_display(); + %domconfig = + &Apache::lonnet::get_dom('configuration',['requestcourses'],$ccdomain); + } elsif ($context eq 'requestauthor') { + %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname,'requestauthor'); + @usertools = ('requestauthor'); + @options =('norequest','approval','automatic'); + %reqtitles = &requestauthor_titles(); + %reqdisplay = &requestauthor_display(); + %domconfig = + &Apache::lonnet::get_dom('configuration',['requestauthor'],$ccdomain); + } elsif ($context eq 'authordefaults') { + %domconfig = + &Apache::lonnet::get_dom('configuration',['quotas','authordefaults'],$ccdomain); + %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname,'tools.webdav', + 'authoreditors','authormanagers', + 'domcoord.author'); + @usertools = ('webdav','editors','managers'); + $colspan = ' colspan="2"'; } else { %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname, - 'tools.aboutme','tools.portfolio','tools.blog'); - @usertools = ('aboutme','blog','portfolio'); + 'tools.aboutme','tools.portfolio','tools.blog', + 'tools.timezone','tools.portaccess'); + @usertools = ('aboutme','blog','portfolio','portaccess','timezone'); + $colspan = ' colspan="2"'; } foreach my $item (@usertools) { - my ($custom_access,$curr_access,$cust_on,$cust_off,$tool_on,$tool_off); + my ($custom_access,$curr_access,$cust_on,$cust_off,$tool_on,$tool_off, + $currdisp,$custdisp,$custradio,$onclick); $cust_off = 'checked="checked" '; $tool_on = 'checked="checked" '; - $curr_access = + $curr_access = &Apache::lonnet::usertools_access($ccuname,$ccdomain,$item,undef, - $context); - if ($userenv{$context.'.'.$item} eq '') { - $custom_access = 'default'; - if (!$curr_access) { - $tool_off = 'checked="checked" '; - $tool_on = ''; + $context,\%userenv,'', + {'is_adv' => $isadv}); + if ($context eq 'requestauthor') { + if ($userenv{$context} ne '') { + $cust_on = ' checked="checked" '; + $cust_off = ''; + } + } elsif ($context eq 'authordefaults') { + if ($item eq 'editors') { + if ($userenv{'author'.$item} ne '') { + $cust_on = ' checked="checked" '; + $cust_off = ''; + } + } elsif ($item eq 'webdav') { + if ($userenv{'tools.'.$item} ne '') { + $cust_on = ' checked="checked" '; + $cust_off = ''; + } } - } else { - $custom_access = 'custom'; + } elsif ($userenv{$context.'.'.$item} ne '') { $cust_on = ' checked="checked" '; $cust_off = ''; - if ($userenv{$context.'.'.$item} == 0) { - $tool_off = 'checked="checked" '; - $tool_on = ''; + } + if ($context eq 'requestcourses') { + if ($userenv{$context.'.'.$item} eq '') { + $custom_access = &mt('Currently from default setting.'); + $customsty = ' style="display:none;"'; + } else { + $custom_access = &mt('Currently from custom setting.'); + $customsty = ' style="display:block;"'; + } + } elsif ($context eq 'requestauthor') { + if ($userenv{$context} eq '') { + $custom_access = &mt('Currently from default setting.'); + $customsty = ' style="display:none;"'; + } else { + $custom_access = &mt('Currently from custom setting.'); + $customsty = ' style="display:block;"'; + } + } elsif ($item eq 'editors') { + if ($userenv{'author'.$item} eq '') { + if (ref($domconfig{'authordefaults'}{'editors'}) eq 'ARRAY') { + @defaulteditors = @{$domconfig{'authordefaults'}{'editors'}}; + } else { + @defaulteditors = ('edit','xml'); + } + $custom_access = &mt('Can use: [_1]', + join(', ', map { $lt{$_} } @defaulteditors)); + $editorsty = ' style="display:none;"'; + } else { + $custom_access = &mt('Currently from custom setting.'); + foreach my $editor (split(/,/,$userenv{'author'.$item})) { + if ($editor =~ /^(edit|daxe|xml)$/) { + push(@customeditors,$editor); + } + } + if (@customeditors) { + if (@customeditors > 1) { + $custom_access .= '
'; + } else { + $custom_access .= ' '; + } + $custom_access .= &mt('Can use: [_1]', + join(', ', map { $lt{$_} } @customeditors)). + ''; + } else { + $custom_access .= ' '.&mt('No available editors'); + } + $editorsty = ' style="display:block;"'; + } + } elsif ($item eq 'managers') { + my %ca_roles = &Apache::lonnet::get_my_roles($ccuname,$ccdomain,undef, + ['active','future'],['ca']); + if (keys(%ca_roles)) { + foreach my $entry (sort(keys(%ca_roles))) { + if ($entry =~ /^($match_username\:$match_domain):ca$/) { + my $user = $1; + unless ($user eq "$ccuname:$ccdomain") { + push(@possmanagers,$user); + } + } + } + } + if ($userenv{'author'.$item} eq '') { + $custom_access = &mt('Currently author manages co-author roles'); + } else { + if (keys(%ca_roles)) { + foreach my $user (split(/,/,$userenv{'author'.$item})) { + if ($user =~ /^($match_username):($match_domain)$/) { + if (exists($ca_roles{$user.':ca'})) { + unless ($user eq "$ccuname:$ccdomain") { + push(@custommanagers,$user); + } + } + } + } + } + if (@custommanagers) { + $custom_access = &mt('Co-authors who manage co-author roles: [_1]', + join(', ',@custommanagers)); + } else { + $custom_access = &mt('Currently author manages co-author roles'); + } + } + } else { + my $current = $userenv{$context.'.'.$item}; + if ($item eq 'webdav') { + $current = $userenv{'tools.webdav'}; + } + if ($current eq '') { + $custom_access = + &mt('Availability determined currently from default setting.'); + if (!$curr_access) { + $tool_off = 'checked="checked" '; + $tool_on = ''; + } + $customsty = ' style="display:none;"'; + } else { + $custom_access = + &mt('Availability determined currently from custom setting.'); + if ($current == 0) { + $tool_off = 'checked="checked" '; + $tool_on = ''; + } + $customsty = ' style="display:inline;"'; } } $output .= ' '."\n". - ' '.$lt{$item}.''."\n". + ' '.$lt{$item}.''."\n". ' '."\n". + &Apache::loncommon::start_data_table_row()."\n"; + if (($context eq 'requestcourses') || ($context eq 'requestauthor')) { + my ($curroption,$currlimit,$customsty); + my $envkey = $context.'.'.$item; + if ($context eq 'requestauthor') { + $envkey = $context; + } + if ($userenv{$envkey} ne '') { + $curroption = $userenv{$envkey}; + $customsty = ' style="display:block"'; + } else { + $customsty = ' style="display:none"'; + my (@inststatuses); + if ($context eq 'requestcourses') { + $curroption = + &Apache::loncoursequeueadmin::get_processtype('course',$ccuname,$ccdomain, + $isadv,$ccdomain,$item, + \@inststatuses,\%domconfig); + } else { + $curroption = + &Apache::loncoursequeueadmin::get_processtype('requestauthor',$ccuname,$ccdomain, + $isadv,$ccdomain,undef, + \@inststatuses,\%domconfig); + } + } + if (!$curroption) { + $curroption = 'norequest'; + } + my $name = 'crsreq_'.$item; + if ($context eq 'requestauthor') { + $name = $item; + } + $onclick = ' onclick="javascript:toggleCustom(this.form,'."'customtext_$item','custom$item'".');"'; + if ($curroption =~ /^autolimit=(\d*)$/) { + $currlimit = $1; + if ($currlimit eq '') { + $currdisp = &mt('Yes, automatic creation'); + } else { + $currdisp = &mt('Yes, up to [quant,_1,request]/user',$currlimit); + } + } else { + $currdisp = $reqdisplay{$curroption}; + } + $custdisp = '
'; + foreach my $option (@options) { + my $val = $option; + if ($option eq 'norequest') { + $val = 0; + } + if ($option eq 'validate') { + my $canvalidate = 0; + if (ref($validations{$item}) eq 'HASH') { + if ($validations{$item}{'_custom_'}) { + $canvalidate = 1; + } + } + next if (!$canvalidate); + } + my $checked = ''; + if ($option eq $curroption) { + $checked = ' checked="checked"'; + } elsif ($option eq 'autolimit') { + if ($curroption =~ /^autolimit/) { + $checked = ' checked="checked"'; + } + } + if ($option eq 'autolimit') { + $custdisp .= '
'; + } + $custdisp .= ' '; + if ($option eq 'autolimit') { + $custdisp .= ' '. + $reqtitles{'unlimited'}.''; + } else { + $custdisp .= ''; + } + $custdisp .= ' '; + } + $custdisp .= '
'; + $custradio = '
'.$custdisp; + } elsif ($item eq 'editors') { + $output .= ''.$custom_access.''."\n". + &Apache::loncommon::end_data_table_row()."\n"; + unless (&Apache::lonnet::allowed('udp',$ccdomain)) { + $output .= &Apache::loncommon::start_data_table_row()."\n". + ''. + $lt{'chse'}.': '.(' ' x3). + '
'. + '
'; + foreach my $editor ('edit','xml','daxe') { + my $checked; + if ($userenv{'author'.$item} eq '') { + if (grep(/^\Q$editor\E$/,@defaulteditors)) { + $checked = ' checked="checked"'; + } + } elsif (grep(/^\Q$editor\E$/,@customeditors)) { + $checked = ' checked="checked"'; + } + $output .= ' '; + } + $output .= '
'. + &Apache::loncommon::end_data_table_row()."\n"; + } + } elsif ($item eq 'managers') { + $output .= ''.$custom_access.''."\n". + &Apache::loncommon::end_data_table_row()."\n"; + unless ((&Apache::lonnet::allowed('udp',$ccdomain)) || + (($userenv{'domcoord.author'} eq 'blocked') && + (($env{'user.name'} ne $ccuname) || ($env{'user.domain'} ne $ccdomain)))) { + $output .= + &Apache::loncommon::start_data_table_row()."\n". + ''; + if (@possmanagers) { + $output .= &mt('Select manager(s)').': '; + foreach my $user (@possmanagers) { + my $checked; + if (grep(/^\Q$user\E$/,@custommanagers)) { + $checked = ' checked="checked"'; + } + $output .= ' '; + } + } else { + $output .= &mt('No co-author roles assignable as manager'); + } + $output .= ''. + &Apache::loncommon::end_data_table_row()."\n"; + } + } else { + $currdisp = ($curr_access?&mt('Yes'):&mt('No')); + my $name = $context.'_'.$item; + $onclick = 'onclick="javascript:toggleCustom(this.form,'."'customtext_$item','custom$item'".');" '; + $custdisp = ' '; + $custradio = ''. + '--'.$lt{'cusa'}.': '.$custdisp.''; + } + unless (($item eq 'editors') || ($item eq 'managers')) { + $output .= ' '.$custom_access.(' 'x4). + $lt{'avai'}.': '.$currdisp.''."\n". + &Apache::loncommon::end_data_table_row()."\n"; + unless (&Apache::lonnet::allowed('udp',$ccdomain)) { + $output .= &Apache::loncommon::start_data_table_row()."\n". - ' '.&mt('Availability determined currently from [_1] setting.',$custom_access). - '     '.$lt{'avai'}.': '. - ($curr_access?&mt('Yes'):&mt('No')).''."\n". - &Apache::loncommon::end_data_table_row()."\n". - &Apache::loncommon::start_data_table_row()."\n". - ' '.$lt{'chse'}.': '.(' ' x3). + ''; + if ($colspan) { + $output .= ''; + } + $output .= $custradio.''. + &Apache::loncommon::end_data_table_row()."\n"; + } + } + } + return $output; +} + +sub coursereq_externaluser { + my ($ccuname,$ccdomain,$cdom) = @_; + my (@usertools,@options,%validations,%userenv,$output); + my %lt = &Apache::lonlocal::texthash ( + 'official' => 'Can request creation of official courses', + 'unofficial' => 'Can request creation of unofficial courses', + 'community' => 'Can request creation of communities', + 'textbook' => 'Can request creation of textbook courses', + 'placement' => 'Can request creation of placement tests', + ); + + %userenv = &Apache::lonnet::userenvironment($ccdomain,$ccuname, + 'reqcrsotherdom.official','reqcrsotherdom.unofficial', + 'reqcrsotherdom.community','reqcrsotherdom.textbook', + 'reqcrsotherdom.placement'); + @usertools = ('official','unofficial','community','textbook','placement'); + @options = ('approval','validate','autolimit'); + %validations = &Apache::lonnet::auto_courserequest_checks($cdom); + my $optregex = join('|',@options); + my %reqtitles = &courserequest_titles(); + foreach my $item (@usertools) { + my ($curroption,$currlimit,$tooloff); + if ($userenv{'reqcrsotherdom.'.$item} ne '') { + my @curr = split(',',$userenv{'reqcrsotherdom.'.$item}); + foreach my $req (@curr) { + if ($req =~ /^\Q$cdom\E\:($optregex)=?(\d*)$/) { + $curroption = $1; + $currlimit = $2; + last; + } + } + if (!$curroption) { + $curroption = 'norequest'; + $tooloff = ' checked="checked"'; + } + } else { + $curroption = 'norequest'; + $tooloff = ' checked="checked"'; + } + $output.= &Apache::loncommon::start_data_table_row()."\n". + ' '.$lt{$item}.': '. + ''; + foreach my $option (@options) { + if ($option eq 'validate') { + my $canvalidate = 0; + if (ref($validations{$item}) eq 'HASH') { + if ($validations{$item}{'_external_'}) { + $canvalidate = 1; + } + } + next if (!$canvalidate); + } + my $checked = ''; + if ($option eq $curroption) { + $checked = ' checked="checked"'; + } + $output .= ''; + } + $output .= '
'."\n". + ''; + if ($option eq 'autolimit') { + $output .= ' '. + '
'.$reqtitles{'unlimited'}; + } else { + $output .= ''; + } + $output .= '
'."\n". &Apache::loncommon::end_data_table_row()."\n"; } return $output; } +sub domainrole_req { + my ($ccuname,$ccdomain) = @_; + return '

'. + &mt('Can Request Assignment of Domain Roles?'). + '

'."\n". + &Apache::loncommon::start_data_table(). + &build_tools_display($ccuname,$ccdomain, + 'requestauthor'). + &Apache::loncommon::end_data_table(); +} + +sub authoring_defaults { + my ($ccuname,$ccdomain) = @_; + return '

'. + &mt('Authoring Space defaults (if role assigned)'). + '

'."\n". + &Apache::loncommon::start_data_table(). + &build_tools_display($ccuname,$ccdomain, + 'authordefaults'). + &user_quotas($ccuname,$ccdomain,'author'). + &Apache::loncommon::end_data_table(); +} + +sub courserequest_titles { + my %titles = &Apache::lonlocal::texthash ( + official => 'Official', + unofficial => 'Unofficial', + community => 'Communities', + textbook => 'Textbook', + placement => 'Placement Tests', + lti => 'LTI Provider', + norequest => 'Not allowed', + approval => 'Approval by Dom. Coord.', + validate => 'With validation', + autolimit => 'Numerical limit', + unlimited => '(blank for unlimited)', + ); + return %titles; +} + +sub courserequest_display { + my %titles = &Apache::lonlocal::texthash ( + approval => 'Yes, need approval', + validate => 'Yes, with validation', + norequest => 'No', + ); + return %titles; +} + +sub requestauthor_titles { + my %titles = &Apache::lonlocal::texthash ( + norequest => 'Not allowed', + approval => 'Approval by Dom. Coord.', + automatic => 'Automatic approval', + ); + return %titles; + +} + +sub requestauthor_display { + my %titles = &Apache::lonlocal::texthash ( + approval => 'Yes, need approval', + automatic => 'Yes, automatic approval', + norequest => 'No', + ); + return %titles; +} + +sub requestchange_display { + my %titles = &Apache::lonlocal::texthash ( + approval => "availability set to 'on' (approval required)", + automatic => "availability set to 'on' (automatic approval)", + norequest => "availability set to 'off'", + ); + return %titles; +} + +sub curr_requestauthor { + my ($uname,$udom,$isadv,$inststatuses,$domconfig) = @_; + return unless ((ref($inststatuses) eq 'ARRAY') && (ref($domconfig) eq 'HASH')); + if ($uname eq '' || $udom eq '') { + $uname = $env{'user.name'}; + $udom = $env{'user.domain'}; + $isadv = $env{'user.adv'}; + } + my (%userenv,%settings,$val); + my @options = ('automatic','approval'); + %userenv = + &Apache::lonnet::userenvironment($udom,$uname,'requestauthor','inststatus'); + if ($userenv{'requestauthor'}) { + $val = $userenv{'requestauthor'}; + @{$inststatuses} = ('_custom_'); + } else { + my %alltasks; + if (ref($domconfig->{'requestauthor'}) eq 'HASH') { + %settings = %{$domconfig->{'requestauthor'}}; + if (($isadv) && ($settings{'_LC_adv'} ne '')) { + $val = $settings{'_LC_adv'}; + @{$inststatuses} = ('_LC_adv_'); + } else { + if ($userenv{'inststatus'} ne '') { + @{$inststatuses} = split(',',$userenv{'inststatus'}); + } else { + @{$inststatuses} = ('default'); + } + foreach my $status (@{$inststatuses}) { + if (exists($settings{$status})) { + my $value = $settings{$status}; + next unless ($value); + unless (exists($alltasks{$value})) { + if (ref($alltasks{$value}) eq 'ARRAY') { + unless(grep(/^\Q$status\E$/,@{$alltasks{$value}})) { + push(@{$alltasks{$value}},$status); + } + } else { + @{$alltasks{$value}} = ($status); + } + } + } + } + foreach my $option (@options) { + if ($alltasks{$option}) { + $val = $option; + last; + } + } + } + } + } + return $val; +} + # =================================================================== Phase one sub print_username_entry_form { - my ($r,$context,$response,$srch,$forcenewuser) = @_; + my ($r,$context,$response,$srch,$forcenewuser,$crstype,$brcrum, + $permission) = @_; my $defdom=$env{'request.role.domain'}; my $formtoset = 'crtuser'; if (exists($env{'form.startrolename'})) { @@ -299,77 +880,180 @@ sub print_username_entry_form { my $jscript = &Apache::loncommon::studentbrowser_javascript()."\n". ''."\n"; - my %loaditems = ( - 'onload' => "javascript:setFormElements(document.$formtoset)", - ); - my %breadcrumb_text = &singleuser_breadcrumb(); - my $start_page = - &Apache::loncommon::start_page('User Management', - $jscript,{'add_entries' => \%loaditems,}); - if ($env{'form.action'} eq 'custom') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage(document.crtuser)", - text=>"Pick custom role",}); - } else { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage(document.crtuser)", - text=>$breadcrumb_text{'search'}, - faq=>282,bug=>'Instructor Interface',}); + my %existingroles=&Apache::lonuserutils::my_custom_roles($crstype); + if (($env{'form.action'} eq 'custom') && (keys(%existingroles) > 0) + && (&Apache::lonnet::allowed('mcr','/'))) { + $jscript .= &customrole_javascript(); } my $helpitem = 'Course_Change_Privileges'; if ($env{'form.action'} eq 'custom') { - $helpitem = 'Course_Editing_Custom_Roles'; + if ($context eq 'course') { + $helpitem = 'Course_Editing_Custom_Roles'; + } elsif ($context eq 'domain') { + $helpitem = 'Domain_Editing_Custom_Roles'; + } } elsif ($env{'form.action'} eq 'singlestudent') { $helpitem = 'Course_Add_Student'; + } elsif ($env{'form.action'} eq 'accesslogs') { + $helpitem = 'Domain_User_Access_Logs'; + } elsif ($context eq 'author') { + $helpitem = 'Author_Change_Privileges'; + } elsif ($context eq 'domain') { + if ($permission->{'cusr'}) { + $helpitem = 'Domain_Change_Privileges'; + } elsif ($permission->{'view'}) { + $helpitem = 'Domain_View_Privileges'; + } else { + undef($helpitem); + } } - my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('User Management', - $helpitem); - my %existingroles=&Apache::lonuserutils::my_custom_roles(); - my $choice=&Apache::loncommon::select_form('make new role','rolename', - ('make new role' => 'Generate new role ...',%existingroles)); + my %breadcrumb_text = &singleuser_breadcrumb($crstype,$context,$defdom); + if ($env{'form.action'} eq 'custom') { + push(@{$brcrum}, + {href=>"javascript:backPage(document.crtuser)", + text=>"Pick custom role", + help => $helpitem,} + ); + } else { + push (@{$brcrum}, + {href => "javascript:backPage(document.crtuser)", + text => $breadcrumb_text{'search'}, + help => $helpitem, + faq => 282, + bug => 'Instructor Interface',} + ); + } + my %loaditems = ( + 'onload' => "javascript:setFormElements(document.$formtoset)", + ); + my $args = {bread_crumbs => $brcrum, + bread_crumbs_component => 'User Management', + add_entries => \%loaditems,}; + $r->print(&Apache::loncommon::start_page('User Management',$jscript,$args)); + my %lt=&Apache::lonlocal::texthash( 'srst' => 'Search for a user and enroll as a student', + 'srme' => 'Search for a user and enroll as a member', 'srad' => 'Search for a user and modify/add user information or roles', + 'srvu' => 'Search for a user and view user information and roles', + 'srva' => 'Search for a user and view access log information', 'usr' => "Username", 'dom' => "Domain", - 'ecrp' => "Edit Custom Role Privileges", - 'nr' => "Name of Role", + 'ecrp' => "Define or Edit Custom Role", + 'nr' => "role name", 'cre' => "Next", ); - $r->print($start_page."\n".$crumbs); + if ($env{'form.action'} eq 'custom') { if (&Apache::lonnet::allowed('mcr','/')) { - $r->print(< - - -

$lt{'ecrp'}

-$choice $lt{'nr'}:
- - -ENDCUSTOM + my $newroletext = &mt('Define new custom role:'); + $r->print('
'. + ''. + ''. + '

'.$lt{'ecrp'}.'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_row(). + ''); + if (keys(%existingroles) > 0) { + $r->print('
'); + } else { + $r->print('
'.$newroletext.''); + } + $r->print(''.$lt{'nr'}.'
'. + &Apache::loncommon::end_data_table_row()); + if (keys(%existingroles) > 0) { + $r->print(&Apache::loncommon::start_data_table_row().'
'. + ''. + '
'. + ''. + ''. + &Apache::loncommon::end_data_table_row()); + } + $r->print(&Apache::loncommon::end_data_table().'

'. + '

'. + '
'); } } else { my $actiontext = $lt{'srad'}; + my $fixeddom; if ($env{'form.action'} eq 'singlestudent') { - $actiontext = $lt{'srst'}; + if ($crstype eq 'Community') { + $actiontext = $lt{'srme'}; + } else { + $actiontext = $lt{'srst'}; + } + } elsif ($env{'form.action'} eq 'accesslogs') { + $actiontext = $lt{'srva'}; + $fixeddom = 1; + } elsif (($env{'form.action'} eq 'singleuser') && + ($context eq 'domain') && (!&Apache::lonnet::allowed('mau',$defdom))) { + $actiontext = $lt{'srvu'}; + $fixeddom = 1; } - $r->print(" -

$actiontext

"); + $r->print("

$actiontext

"); if ($env{'form.origform'} ne 'crtusername') { - $r->print("\n".$response); + if ($response) { + $r->print("\n
$response
". + '
'); + } } - $r->print(&entry_form($defdom,$srch,$forcenewuser,$context,$response)); + $r->print(&entry_form($defdom,$srch,$forcenewuser,$context,$response,$crstype,$fixeddom)); } - $r->print(&Apache::loncommon::end_page()); +} + +sub customrole_javascript { + my $js = <<"END"; + +END + return $js; } sub entry_form { - my ($dom,$srch,$forcenewuser,$context,$responsemsg) = @_; - my %domconf = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom); + my ($dom,$srch,$forcenewuser,$context,$responsemsg,$crstype,$fixeddom) = @_; my ($usertype,$inexact); if (ref($srch) eq 'HASH') { if (($srch->{'srchin'} eq 'dom') && @@ -377,25 +1061,35 @@ sub entry_form { ($srch->{'srchtype'} eq 'exact') && ($srch->{'srchdomain'} ne '') && ($srch->{'srchterm'} ne '')) { + my (%curr_rules,%got_rules); my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($srch->{'srchdomain'},'username'); - $usertype = &Apache::lonuserutils::check_usertype($srch->{'srchdomain'},$srch->{'srchterm'},$rules); + $usertype = &Apache::lonuserutils::check_usertype($srch->{'srchdomain'},$srch->{'srchterm'},$rules,\%curr_rules,\%got_rules); } else { $inexact = 1; } } - my $cancreate = - &Apache::lonuserutils::can_create_user($dom,$context,$usertype); - my $userpicker = + my ($cancreate,$noinstd); + if ($env{'form.action'} eq 'accesslogs') { + $noinstd = 1; + } else { + $cancreate = + &Apache::lonuserutils::can_create_user($dom,$context,$usertype); + } + my ($userpicker,$cansearch) = &Apache::loncommon::user_picker($dom,$srch,$forcenewuser, - 'document.crtuser',$cancreate,$usertype); + 'document.crtuser',$cancreate,$usertype,$context,$fixeddom,$noinstd); my $srchbutton = &mt('Search'); if ($env{'form.action'} eq 'singlestudent') { $srchbutton = &mt('Search and Enroll'); + } elsif ($env{'form.action'} eq 'accesslogs') { + $srchbutton = &mt('Search'); } elsif ($cancreate && $responsemsg ne '' && $inexact) { $srchbutton = &mt('Search or Add New User'); } - my $output = <<"ENDBLOCK"; + my $output; + if ($cansearch) { + $output = <<"ENDBLOCK";
@@ -403,11 +1097,25 @@ $userpicker
ENDBLOCK - if ($env{'form.phase'} eq '') { + } else { + $output = '

'.$userpicker.'

'; + } + if (($env{'form.phase'} eq '') && ($env{'form.action'} ne 'accesslogs') && + (!(($env{'form.action'} eq 'singleuser') && ($context eq 'domain') && + (!&Apache::lonnet::allowed('mau',$env{'request.role.domain'}))))) { my $defdom=$env{'request.role.domain'}; - my $domform = &Apache::loncommon::select_dom_form($defdom,'srchdomain'); + my ($trusted,$untrusted); + if ($context eq 'course') { + ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('enroll',$defdom); + } elsif ($context eq 'author') { + ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('othcoau',$defdom); + } elsif ($context eq 'domain') { + ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('domroles',$defdom); + } + my $domform = &Apache::loncommon::select_dom_form($defdom,'srchdomain',undef,undef,undef,$trusted,$untrusted); my %lt=&Apache::lonlocal::texthash( 'enro' => 'Enroll one student', + 'enrm' => 'Enroll one member', 'admo' => 'Add/modify a single user', 'crea' => 'create new user if required', 'uskn' => "username is known", @@ -419,8 +1127,12 @@ ENDBLOCK ); my $sellink=&Apache::loncommon::selectstudent_link('crtusername','srchterm','srchdomain'); my ($title,$buttontext,$showresponse); - if ($env{'form.action'} eq 'singlestudent') { - $title = $lt{'enro'}; + if ($env{'form.action'} eq 'singlestudent') { + if ($crstype eq 'Community') { + $title = $lt{'enrm'}; + } else { + $title = $lt{'enro'}; + } $buttontext = $lt{'enrl'}; } else { $title = $lt{'admo'}; @@ -466,12 +1178,7 @@ sub user_modification_js { return < - - function pclose() { - parmwin=window.open("/adm/rat/empty.html","LONCAPAparms", - "height=350,width=350,scrollbars=no,menubar=no"); - parmwin.close(); - } +// END } # =================================================================== Phase two sub print_user_selection_page { - my ($r,$response,$srch,$srch_results,$srcharray,$context) = @_; + my ($r,$response,$srch,$srch_results,$srcharray,$context,$opener_elements,$crstype,$brcrum) = @_; my @fields = ('username','domain','lastname','firstname','permanentemail'); my $sortby = $env{'form.sortby'}; @@ -502,6 +1209,7 @@ sub print_user_selection_page { my $jscript = (< +// ENDSCRIPT my %lt=&Apache::lonlocal::texthash( 'usrch' => "User Search to add/modify roles", 'stusrch' => "User Search to enroll student", + 'memsrch' => "User Search to enroll member", + 'srcva' => "Search for a user and view access log information", + 'usrvu' => "User Search to view user roles", 'usel' => "Select a user to add/modify roles", - 'stusel' => "Select a user to enroll as a student", + 'suvr' => "Select a user to view roles", + 'stusel' => "Select a user to enroll as a student", + 'memsel' => "Select a user to enroll as a member", + 'vacsel' => "Select a user to view access log", 'username' => "username", 'domain' => "domain", 'lastname' => "last name", 'firstname' => "first name", 'permanentemail' => "permanent e-mail", ); - $r->print(&Apache::loncommon::start_page('User Management',$jscript)); - - my %breadcrumb_text = &singleuser_breadcrumb(); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage(document.usersrchform,'','')", - text=>$breadcrumb_text{'search'}, - faq=>282,bug=>'Instructor Interface',}, - {href=>"javascript:backPage(document.usersrchform,'get_user_info','select')", - text=>$breadcrumb_text{'userpicked'}, - faq=>282,bug=>'Instructor Interface',}); - if ($env{'form.action'} eq 'singleuser') { - $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', - 'Course_Change_Privileges')); - $r->print("$lt{'usrch'}
"); - $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context)); - $r->print('

'.$lt{'usel'}.'

'); - } elsif ($env{'form.action'} eq 'singlestudent') { - $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', - 'Course_Add_Student')); - $r->print($jscript."$lt{'stusrch'}
"); - $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context)); - $r->print('

'.$lt{'stusel'}.'

'); + if ($context eq 'requestcrs') { + $r->print('
'); + } else { + my %breadcrumb_text = &singleuser_breadcrumb($crstype,$context,$srch->{'srchdomain'}); + my $helpitem; + if ($env{'form.action'} eq 'singleuser') { + $helpitem = 'Course_Change_Privileges'; + } elsif ($env{'form.action'} eq 'singlestudent') { + $helpitem = 'Course_Add_Student'; + } elsif ($context eq 'author') { + $helpitem = 'Author_Change_Privileges'; + } elsif ($context eq 'domain') { + $helpitem = 'Domain_Change_Privileges'; + } + push (@{$brcrum}, + {href => "javascript:backPage(document.usersrchform,'','')", + text => $breadcrumb_text{'search'}, + faq => 282, + bug => 'Instructor Interface',}, + {href => "javascript:backPage(document.usersrchform,'get_user_info','select')", + text => $breadcrumb_text{'userpicked'}, + faq => 282, + bug => 'Instructor Interface', + help => $helpitem} + ); + $r->print(&Apache::loncommon::start_page('User Management',$jscript,{bread_crumbs => $brcrum})); + if ($env{'form.action'} eq 'singleuser') { + my $readonly; + if (($context eq 'domain') && (!&Apache::lonnet::allowed('mau',$srch->{'srchdomain'}))) { + $readonly = 1; + $r->print("$lt{'usrvu'}
"); + } else { + $r->print("$lt{'usrch'}
"); + } + $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context,undef,$crstype)); + if ($readonly) { + $r->print('

'.$lt{'suvr'}.'

'); + } else { + $r->print('

'.$lt{'usel'}.'

'); + } + } elsif ($env{'form.action'} eq 'singlestudent') { + $r->print($jscript.""); + if ($crstype eq 'Community') { + $r->print($lt{'memsrch'}); + } else { + $r->print($lt{'stusrch'}); + } + $r->print("
"); + $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context,undef,$crstype)); + $r->print('

'); + if ($crstype eq 'Community') { + $r->print($lt{'memsel'}); + } else { + $r->print($lt{'stusel'}); + } + $r->print('

'); + } elsif ($env{'form.action'} eq 'accesslogs') { + $r->print("$lt{'srcva'}
"); + $r->print(&entry_form($srch->{'srchdomain'},$srch,undef,$context,undef,undef,1)); + $r->print('

'.$lt{'vacsel'}.'

'); + } } - $r->print('
'. + $r->print(''. &Apache::loncommon::start_data_table()."\n". &Apache::loncommon::start_data_table_header_row()."\n". ' '."\n"); @@ -570,8 +1324,20 @@ ENDSCRIPT foreach my $user (@sorted_users) { my ($uname,$udom) = split(/:/,$user); + my $onclick; + if ($context eq 'requestcrs') { + $onclick = + 'onclick="javascript:gochoose('."'$uname','$udom',". + "'$srch_results->{$user}->{firstname}',". + "'$srch_results->{$user}->{lastname}',". + "'$srch_results->{$user}->{permanentemail}'".');"'; + } else { + $onclick = + ' onclick="javascript:pickuser('."'".$uname."'".','."'".$udom."'".');"'; + } $r->print(&Apache::loncommon::start_data_table_row(). - ''. + ''. ''.$uname.''. ''.$udom.''); foreach my $field ('lastname','firstname','permanentemail') { @@ -591,11 +1357,15 @@ ENDSCRIPT ' '."\n". ' '."\n". ' '."\n"); - $r->print($response.'
'.&Apache::loncommon::end_page()); + if ($context eq 'requestcrs') { + $r->print($opener_elements.'
'); + } else { + $r->print($response.''); + } } sub print_user_query_page { - my ($r,$caller) = @_; + my ($r,$caller,$brcrum) = @_; # FIXME - this is for a network-wide name search (similar to catalog search) # To use frames with similar behavior to catalog/portfolio search. # To be implemented. @@ -603,11 +1373,13 @@ sub print_user_query_page { } sub print_user_modification_page { - my ($r,$ccuname,$ccdomain,$srch,$response,$context,$permission) = @_; + my ($r,$ccuname,$ccdomain,$srch,$response,$context,$permission,$crstype, + $brcrum,$showcredits) = @_; if (($ccuname eq '') || ($ccdomain eq '')) { my $usermsg = &mt('No username and/or domain provided.'); $env{'form.phase'} = ''; - &print_username_entry_form($r,$context,$usermsg); + &print_username_entry_form($r,$context,$usermsg,'','',$crstype,$brcrum, + $permission); return; } my ($form,$formname); @@ -626,7 +1398,8 @@ sub print_user_modification_page { my ($rules,$ruleorder) = &Apache::lonnet::inst_userrules($ccdomain,'username'); $usertype = - &Apache::lonuserutils::check_usertype($ccdomain,$ccuname,$rules); + &Apache::lonuserutils::check_usertype($ccdomain,$ccuname,$rules, + \%curr_rules,\%got_rules); my $cancreate = &Apache::lonuserutils::can_create_user($ccdomain,$context, $usertype); @@ -638,17 +1411,25 @@ sub print_user_modification_page { ); my $response; if ($env{'form.origform'} eq 'crtusername') { - $response = ''.&mt('No match was found for the username ([_1]) in LON-CAPA domain: [_2]',$ccuname,$ccdomain). + $response = ''. + &mt('No match found for the username [_1] in LON-CAPA domain: [_2]', + ''.$ccuname.'',$ccdomain). '
'; } $response .= '

' .&mt("You are not authorized to create new $usertypetext{$usertype} users in this domain.") - .' ' - .&mt('Please contact the [_1]helpdesk[_2] for assistance.' - ,'','') - .'


'; + .' '; + if ($context eq 'domain') { + $response .= &mt('Please contact a [_1] for assistance.', + &Apache::lonnet::plaintext('dc')); + } else { + $response .= &mt('Please contact the [_1]helpdesk[_2] for assistance.' + ,'',''); + } + $response .= '


'; $env{'form.phase'} = ''; - &print_username_entry_form($r,$context,$response); + &print_username_entry_form($r,$context,$response,undef,undef,$crstype,$brcrum, + $permission); return; } $newuser = 1; @@ -672,7 +1453,8 @@ sub print_user_modification_page { 'username'); } $env{'form.phase'} = ''; - &print_username_entry_form($r,$context,$userchkmsg); + &print_username_entry_form($r,$context,$userchkmsg,undef,undef,$crstype,$brcrum, + $permission); return; } } @@ -692,35 +1474,70 @@ sub print_user_modification_page { my $groupslist = &Apache::lonuserutils::get_groupslist(); my $js = &validation_javascript($context,$ccdomain,$pjump_def, - $groupslist,$newuser,$formname,\%loaditem); - my $args = {'add_entries' => \%loaditem}; - if ($env{'form.popup'}) { - $args->{'no_nav_bar'} = 1; - } - my $start_page = - &Apache::loncommon::start_page('User Management',$js,$args); - my %breadcrumb_text = &singleuser_breadcrumb(); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage($form)", - text=>$breadcrumb_text{'search'}, - faq=>282,bug=>'Instructor Interface',}); - - if ($env{'form.phase'} eq 'userpicked') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage($form,'get_user_info','select')", - text=>$breadcrumb_text{'userpicked'}, - faq=>282,bug=>'Instructor Interface',}); - } - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage($form,'$env{'form.phase'}','modify')", - text=>$breadcrumb_text{'modify'}, - faq=>282,bug=>'Instructor Interface',}); + $crstype,$groupslist,$newuser, + $formname,\%loaditem,$permission); + my %breadcrumb_text = &singleuser_breadcrumb($crstype,$context,$ccdomain); my $helpitem = 'Course_Change_Privileges'; if ($env{'form.action'} eq 'singlestudent') { $helpitem = 'Course_Add_Student'; + } elsif ($context eq 'author') { + $helpitem = 'Author_Change_Privileges'; + } elsif ($context eq 'domain') { + $helpitem = 'Domain_Change_Privileges'; + $js .= &set_custom_js(); + } + push (@{$brcrum}, + {href => "javascript:backPage($form)", + text => $breadcrumb_text{'search'}, + faq => 282, + bug => 'Instructor Interface',}); + if ($env{'form.phase'} eq 'userpicked') { + push(@{$brcrum}, + {href => "javascript:backPage($form,'get_user_info','select')", + text => $breadcrumb_text{'userpicked'}, + faq => 282, + bug => 'Instructor Interface',}); + } + push(@{$brcrum}, + {href => "javascript:backPage($form,'$env{'form.phase'}','modify')", + text => $breadcrumb_text{'modify'}, + faq => 282, + bug => 'Instructor Interface', + help => $helpitem}); + my $args = {'add_entries' => \%loaditem, + 'bread_crumbs' => $brcrum, + 'bread_crumbs_component' => 'User Management'}; + if ($env{'form.popup'}) { + $args->{'no_nav_bar'} = 1; } - my $crumbs = &Apache::lonhtmlcommon::breadcrumbs('User Management', - $helpitem); + if (($context eq 'domain') && ($env{'request.role.domain'} eq $ccdomain)) { + my @toggles; + if (&Apache::lonnet::allowed('cau',$ccdomain)) { + my ($isadv,$isauthor) = + &Apache::lonnet::is_advanced_user($ccdomain,$ccuname); + unless ($isauthor) { + push(@toggles,'requestauthor'); + } + push(@toggles,('webdav','editors')); + } + if (&Apache::lonnet::allowed('mut',$ccdomain)) { + push(@toggles,('aboutme','blog','portfolio','portaccess','timezone')); + } + if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) { + push(@toggles,('official','unofficial','community','textbook','placement','lti')); + } + if (@toggles) { + my $onload; + foreach my $item (@toggles) { + $onload .= "toggleCustom(document.cu,'customtext_$item','custom$item');"; + } + $args->{'add_entries'} = { + 'onload' => $onload, + }; + } + } + my $start_page = + &Apache::loncommon::start_page('User Management',$js,$args); my $forminfo =<<"ENDFORMINFO";
@@ -731,46 +1548,92 @@ sub print_user_modification_page { ENDFORMINFO - my %inccourses; - foreach my $key (keys(%env)) { - if ($key=~/^user\.priv\.cm\.\/($match_domain)\/($match_username)/) { - $inccourses{$1.'_'.$2}=1; + my (%inccourses,$roledom,$defaultcredits); + if ($context eq 'course') { + $inccourses{$env{'request.course.id'}}=1; + $roledom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + if ($showcredits) { + $defaultcredits = &Apache::lonuserutils::get_defaultcredits(); + } + } elsif ($context eq 'author') { + $roledom = $env{'request.role.domain'}; + } elsif ($context eq 'domain') { + foreach my $key (keys(%env)) { + $roledom = $env{'request.role.domain'}; + if ($key=~/^user\.priv\.cm\.\/($roledom)\/($match_username)/) { + $inccourses{$1.'_'.$2}=1; + } + } + } else { + foreach my $key (keys(%env)) { + if ($key=~/^user\.priv\.cm\.\/($match_domain)\/($match_username)/) { + $inccourses{$1.'_'.$2}=1; + } } } + my $title = ''; + my $need_quota_js; if ($newuser) { - my $portfolioform; + my ($portfolioform,$domroleform); if ((&Apache::lonnet::allowed('mpq',$env{'request.role.domain'})) || (&Apache::lonnet::allowed('mut',$env{'request.role.domain'}))) { # Current user has quota or user tools modification privileges - $portfolioform = '
'.&portfolio_quota($ccuname,$ccdomain); + $portfolioform = '

'. + &mt('User Tools'). + '

'."\n". + &Apache::loncommon::start_data_table(); + if (&Apache::lonnet::allowed('mut',$ccdomain)) { + $portfolioform .= &build_tools_display($ccuname,$ccdomain,'tools'); + } + if (&Apache::lonnet::allowed('mpq',$ccdomain)) { + $portfolioform .= &user_quotas($ccuname,$ccdomain,'portfolio'); + $need_quota_js = 1; + } + $portfolioform .= &Apache::loncommon::end_data_table(); + } + if ((&Apache::lonnet::allowed('cau',$env{'request.role.domain'})) && + ($ccdomain eq $env{'request.role.domain'})) { + $domroleform = &domainrole_req($ccuname,$ccdomain). + &authoring_defaults($ccuname,$ccdomain); + $need_quota_js = 1; + } + my $readonly; + unless ($permission->{'cusr'}) { + $readonly = 1; } - &initialize_authen_forms($ccdomain,$formname); + &initialize_authen_forms($ccdomain,$formname,'','',$readonly); my %lt=&Apache::lonlocal::texthash( - 'cnu' => 'Create New User', - 'ast' => 'as a student', - 'ind' => 'in domain', 'lg' => 'Login Data', 'hs' => "Home Server", ); $r->print(< +// -

$lt{'cnu'} "$ccuname" $lt{'ind'} $ccdomain ENDTITLE if ($env{'form.action'} eq 'singlestudent') { - $r->print(' ('.$lt{'ast'}.')'); + if ($crstype eq 'Community') { + $title = &mt('Create New User [_1] in domain [_2] as a member', + '"'.$ccuname.'"','"'.$ccdomain.'"'); + } else { + $title = &mt('Create New User [_1] in domain [_2] as a student', + '"'.$ccuname.'"','"'.$ccdomain.'"'); + } + } else { + $title = &mt('Create New User [_1] in domain [_2]', + '"'.$ccuname.'"','"'.$ccdomain.'"'); } - $r->print('

'."\n".'
'); - my $personal_table = - &personal_data_display($ccuname,$ccdomain,$newuser,$context, - $inst_results{$ccuname.':'.$ccdomain}); - $r->print($personal_table); + $r->print('

'.$title.'

'."\n"); + $r->print('
'); + $r->print(&personal_data_display($ccuname,$ccdomain,$newuser,$context, + $inst_results{$ccuname.':'.$ccdomain},$readonly)); + # Option to disable student/employee ID conflict checking not offerred for new users. my ($home_server_pick,$numlib) = &Apache::loncommon::home_server_form_item($ccdomain,'hserver', 'default','hide'); @@ -782,6 +1645,14 @@ $lt{'hs'}: $home_server_pick } else { $r->print($home_server_pick); } + if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) { + $r->print('

'. + &mt('Can Request Creation of Courses/Communities in this Domain?').'

'. + &Apache::loncommon::start_data_table(). + &build_tools_display($ccuname,$ccdomain, + 'requestcourses'). + &Apache::loncommon::end_data_table()); + } $r->print('
'."\n".'

'. $lt{'lg'}.'

'); my ($fixedauth,$varauth,$authmsg); @@ -815,7 +1686,7 @@ KERB } else { if ($authtype eq 'int') { $varauth = '
'. -&mt('[_1] Internally authenticated (with initial password [_2])','','')."'; +&mt('[_1] Internally authenticated (with initial password [_2])','','')."'; } elsif ($authtype eq 'loc') { $varauth = '
'. &mt('[_1] Local Authentication with argument [_2]','','')."\n"; @@ -840,63 +1711,96 @@ ENDAUTH } else { $r->print(&Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc)); } - $r->print($portfolioform); + $r->print($portfolioform.$domroleform); if ($env{'form.action'} eq 'singlestudent') { $r->print(&date_sections_select($context,$newuser,$formname, - $permission)); + $permission,$crstype,$ccuname, + $ccdomain,$showcredits)); } $r->print('
'); } else { # user already exists - my %lt=&Apache::lonlocal::texthash( - 'cup' => "Modify existing user: ", - 'ens' => "Enroll one student: ", - 'id' => "in domain", - ); - $r->print(< -ENDCHANGEUSER + $r->print($start_page.$forminfo); if ($env{'form.action'} eq 'singlestudent') { - $r->print($lt{'ens'}); + if ($crstype eq 'Community') { + $title = &mt('Enroll one member: [_1] in domain [_2]', + '"'.$ccuname.'"','"'.$ccdomain.'"'); + } else { + $title = &mt('Enroll one student: [_1] in domain [_2]', + '"'.$ccuname.'"','"'.$ccdomain.'"'); + } } else { - $r->print($lt{'cup'}); - } - $r->print(' "'.$ccuname.'" '.$lt{'id'}.' "'.$ccdomain.'"'. - "\n".'
'); - my ($personal_table,$showforceid) = - &personal_data_display($ccuname,$ccdomain,$newuser,$context, - $inst_results{$ccuname.':'.$ccdomain}); - $r->print($personal_table); - if ($showforceid) { - $r->print(&Apache::lonuserutils::forceid_change($context)); + if ($permission->{'cusr'}) { + $title = &mt('Modify existing user: [_1] in domain [_2]', + '"'.$ccuname.'"','"'.$ccdomain.'"'); + } else { + $title = &mt('Existing user: [_1] in domain [_2]', + '"'.$ccuname.'"','"'.$ccdomain.'"'); + } } - if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) { - $r->print('

'.&mt('User Can Request Creation of Courses?').'

'. - &Apache::loncommon::start_data_table(). - &build_tools_display($ccuname,$ccdomain,'requestcourses'). - &Apache::loncommon::end_data_table()); + $r->print('

'.$title.'

'."\n"); + $r->print('
'); + $r->print(&personal_data_display($ccuname,$ccdomain,$newuser,$context, + $inst_results{$ccuname.':'.$ccdomain})); + if ((&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) || + (&Apache::lonnet::allowed('udp',$env{'request.role.domain'}))) { + $r->print('

'.&mt('Can Request Creation of Courses/Communities in this Domain?').'

'."\n"); + if (($env{'request.role.domain'} eq $ccdomain) || + (&Apache::lonnet::will_trust('reqcrs',$ccdomain,$env{'request.role.domain'}))) { + $r->print(&Apache::loncommon::start_data_table()); + if ($env{'request.role.domain'} eq $ccdomain) { + $r->print(&build_tools_display($ccuname,$ccdomain,'requestcourses')); + } else { + $r->print(&coursereq_externaluser($ccuname,$ccdomain, + $env{'request.role.domain'})); + } + $r->print(&Apache::loncommon::end_data_table()); + } else { + $r->print(&mt('Domain configuration for this domain prohibits course creation by users from domain: "[_1]"', + &Apache::lonnet::domain($ccdomain,'description'))); + } } $r->print('
'); - my $user_auth_text = &user_authentication($ccuname,$ccdomain,$formname); - my ($user_quota_text,$user_tools_text,$user_reqcrs_text); + my @order = ('auth','quota','tools','requestauthor','authordefaults'); + my %user_text; + my ($isadv,$isauthor) = + &Apache::lonnet::is_advanced_user($ccdomain,$ccuname); + if (((&Apache::lonnet::allowed('cau',$env{'request.role.domain'})) || + (&Apache::lonnet::allowed('udp',$env{'request.role.domain'}))) && + ($env{'request.role.domain'} eq $ccdomain)) { + if (!$isauthor) { + $user_text{'requestauthor'} = &domainrole_req($ccuname,$ccdomain); + } + $user_text{'authordefaults'} = &authoring_defaults($ccuname,$ccdomain); + if (&Apache::lonnet::allowed('cau',$env{'request.role.domain'})) { + $need_quota_js = 1; + } + } + $user_text{'auth'} = &user_authentication($ccuname,$ccdomain,$formname,$crstype,$permission); if ((&Apache::lonnet::allowed('mpq',$ccdomain)) || - (&Apache::lonnet::allowed('mut',$ccdomain))) { + (&Apache::lonnet::allowed('mut',$ccdomain)) || + (&Apache::lonnet::allowed('udp',$ccdomain))) { + $user_text{'quota'} = '

'.&mt('User Tools').'

'."\n". + &Apache::loncommon::start_data_table(); + if ((&Apache::lonnet::allowed('mut',$ccdomain)) || + (&Apache::lonnet::allowed('udp',$ccdomain))) { + $user_text{'quota'} .= &build_tools_display($ccuname,$ccdomain,'tools'); + } # Current user has quota modification privileges - $user_quota_text = &portfolio_quota($ccuname,$ccdomain); + if ((&Apache::lonnet::allowed('mpq',$ccdomain)) || + (&Apache::lonnet::allowed('udp',$ccdomain))) { + $user_text{'quota'} .= &user_quotas($ccuname,$ccdomain,'portfolio'); + $need_quota_js = 1; + } + $user_text{'quota'} .= &Apache::loncommon::end_data_table(); } if (!&Apache::lonnet::allowed('mpq',$ccdomain)) { if (&Apache::lonnet::allowed('mpq',$env{'request.role.domain'})) { - # Get the user's portfolio information - my %portq = &Apache::lonnet::get('environment',['portfolioquota'], - $ccdomain,$ccuname); my %lt=&Apache::lonlocal::texthash( - 'dska' => "Disk space allocated to user's portfolio files", + 'dska' => "Disk quotas for user's portfolio", 'youd' => "You do not have privileges to modify the portfolio quota for this user.", 'ichr' => "If a change is required, contact a domain coordinator for the domain", ); - $user_quota_text = <$lt{'dska'} $lt{'youd'} $lt{'ichr'}: $ccdomain ENDNOPORTPRIV @@ -906,129 +1810,175 @@ ENDNOPORTPRIV if (&Apache::lonnet::allowed('mut',$env{'request.role.domain'})) { my %lt=&Apache::lonlocal::texthash( 'utav' => "User Tools Availability", - 'yodo' => "You do not have privileges to modify Portfolio, Blog or Personal Information Page settings for this user.", + 'yodo' => "You do not have privileges to modify Portfolio, Blog, Personal Information Page, or Time Zone settings for this user.", 'ifch' => "If a change is required, contact a domain coordinator for the domain", ); - $user_tools_text = <$lt{'utav'} $lt{'yodo'} $lt{'ifch'}: $ccdomain ENDNOTOOLSPRIV } } - if ($user_auth_text ne '') { - $r->print('
'.$user_auth_text); - if ($user_quota_text ne '') { - $r->print($user_quota_text); - } - if ($user_tools_text ne '') { - $r->print($user_tools_text); - } - if ($env{'form.action'} eq 'singlestudent') { - $r->print(&date_sections_select($context,$newuser,$formname)); - } - } elsif ($user_quota_text ne '') { - $r->print('
'.$user_quota_text); - if ($user_tools_text ne '') { - $r->print($user_tools_text); - } - if ($env{'form.action'} eq 'singlestudent') { - $r->print(&date_sections_select($context,$newuser,$formname)); - } - } elsif ($user_tools_text ne '') { - $r->print('
'.$user_tools_text); - if ($env{'form.action'} eq 'singlestudent') { - $r->print(&date_sections_select($context,$newuser,$formname)); - } - } else { - if ($env{'form.action'} eq 'singlestudent') { - $r->print('
'. - &date_sections_select($context,$newuser,$formname)); + my $gotdiv = 0; + foreach my $item (@order) { + if ($user_text{$item} ne '') { + unless ($gotdiv) { + $r->print('
'); + $gotdiv = 1; + } + $r->print('
'.$user_text{$item}); } } - $r->print('
'); + if ($env{'form.action'} eq 'singlestudent') { + unless ($gotdiv) { + $r->print('
'); + } + my $credits; + if ($showcredits) { + $credits = &get_user_credits($ccuname,$ccdomain,$defaultcredits); + if ($credits eq '') { + $credits = $defaultcredits; + } + } + $r->print(&date_sections_select($context,$newuser,$formname, + $permission,$crstype,$ccuname, + $ccdomain,$showcredits)); + } + if ($gotdiv) { + $r->print('
'); + } + my $statuses; + if (($context eq 'domain') && (&Apache::lonnet::allowed('udp',$ccdomain)) && + (!&Apache::lonnet::allowed('mau',$ccdomain))) { + $statuses = ['active']; + } elsif (($context eq 'course') && ((&Apache::lonnet::allowed('vcl',$env{'request.course.id'})) || + ($env{'request.course.sec'} && + &Apache::lonnet::allowed('vcl',$env{'request.course.id'}.'/'.$env{'request.course.sec'})))) { + $statuses = ['active']; + } if ($env{'form.action'} ne 'singlestudent') { - &display_existing_roles($r,$ccuname,$ccdomain,\%inccourses); + &display_existing_roles($r,$ccuname,$ccdomain,\%inccourses,$context, + $roledom,$crstype,$showcredits,$statuses); } } ## End of new user/old user logic - if ($env{'form.action'} eq 'singlestudent') { - $r->print('
'."\n"); - } else { - $r->print('

'.&mt('Add Roles').'

'); + my $btntxt; + if ($crstype eq 'Community') { + $btntxt = &mt('Enroll Member'); + } else { + $btntxt = &mt('Enroll Student'); + } + $r->print('
'."\n"); + } elsif ($permission->{'cusr'}) { + $r->print('
'. + '
'.&mt('Add Roles').''); my $addrolesdisplay = 0; if ($context eq 'domain' || $context eq 'author') { $addrolesdisplay = &new_coauthor_roles($r,$ccuname,$ccdomain); } if ($context eq 'domain') { - my $add_domainroles = &new_domain_roles($r); + my $add_domainroles = &new_domain_roles($r,$ccdomain); if (!$addrolesdisplay) { $addrolesdisplay = $add_domainroles; } - $r->print(&course_level_dc($env{'request.role.domain'},'Course')); - $r->print('
'."\n"); + $r->print(&course_level_dc($env{'request.role.domain'},$showcredits)); + $r->print('
'. + '
'."\n"); } elsif ($context eq 'author') { if ($addrolesdisplay) { - $r->print('
print('
'. + '
print(' onClick="auth_check()" \>'."\n"); + $r->print(' onclick="auth_check()" \>'."\n"); } else { - $r->print('onClick="this.form.submit()" \>'."\n"); + $r->print(' onclick="this.form.submit()" \>'."\n"); } } else { - $r->print('
'. + $r->print('
'. + ''. + '
'. &mt('Back to previous page').''); } } else { - $r->print(&course_level_table(%inccourses)); - $r->print('
'."\n"); + $r->print(&course_level_table(\%inccourses,$showcredits,$defaultcredits)); + $r->print('
'. + '
'."\n"); } } $r->print(&Apache::lonhtmlcommon::echo_form_input(['phase','userrole','ccdomain','prevphase','currstate','ccuname','ccdomain'])); $r->print(''); - $r->print(''); - $r->print("".&Apache::loncommon::end_page()); + $r->print('

'); + if ($need_quota_js) { + $r->print(&user_quota_js()); + } return; } sub singleuser_breadcrumb { + my ($crstype,$context,$domain) = @_; my %breadcrumb_text; if ($env{'form.action'} eq 'singlestudent') { - $breadcrumb_text{'search'} = 'Enroll a student'; - $breadcrumb_text{'userpicked'} = 'Select a user', - $breadcrumb_text{'modify'} = 'Set section/dates', + if ($crstype eq 'Community') { + $breadcrumb_text{'search'} = 'Enroll a member'; + } else { + $breadcrumb_text{'search'} = 'Enroll a student'; + } + $breadcrumb_text{'userpicked'} = 'Select a user'; + $breadcrumb_text{'modify'} = 'Set section/dates'; + } elsif ($env{'form.action'} eq 'accesslogs') { + $breadcrumb_text{'search'} = 'View access logs for a user'; + $breadcrumb_text{'userpicked'} = 'Select a user'; + $breadcrumb_text{'activity'} = 'Activity'; + } elsif (($env{'form.action'} eq 'singleuser') && ($context eq 'domain') && + (!&Apache::lonnet::allowed('mau',$domain))) { + $breadcrumb_text{'search'} = "View user's roles"; + $breadcrumb_text{'userpicked'} = 'Select a user'; + $breadcrumb_text{'modify'} = 'User roles'; } else { $breadcrumb_text{'search'} = 'Create/modify a user'; - $breadcrumb_text{'userpicked'} = 'Select a user', - $breadcrumb_text{'modify'} = 'Set user role', + $breadcrumb_text{'userpicked'} = 'Select a user'; + $breadcrumb_text{'modify'} = 'Set user role'; } return %breadcrumb_text; } sub date_sections_select { - my ($context,$newuser,$formname,$permission) = @_; + my ($context,$newuser,$formname,$permission,$crstype,$ccuname,$ccdomain, + $showcredits) = @_; + my $credits; + if ($showcredits) { + my $defaultcredits = &Apache::lonuserutils::get_defaultcredits(); + $credits = &get_user_credits($ccuname,$ccdomain,$defaultcredits); + if ($credits eq '') { + $credits = $defaultcredits; + } + } my $cid = $env{'request.course.id'}; my ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity($cid); my $date_table = '

'.&mt('Starting and Ending Dates').'

'."\n". &Apache::lonuserutils::date_setting_table(undef,undef,$context, undef,$formname,$permission); my $rowtitle = 'Section'; - my $secbox = '

'.&mt('Section').'

'."\n". + my $secbox = '

'.&mt('Section and Credits').'

'."\n". &Apache::lonuserutils::section_picker($cdom,$cnum,'st',$rowtitle, - $permission); + $permission,$context,'',$crstype, + $showcredits,$credits); my $output = $date_table.$secbox; return $output; } sub validation_javascript { - my ($context,$ccdomain,$pjump_def,$groupslist,$newuser,$formname, - $loaditem) = @_; + my ($context,$ccdomain,$pjump_def,$crstype,$groupslist,$newuser,$formname, + $loaditem,$permission) = @_; my $dc_setcourse_code = ''; my $nondc_setsection_code = ''; if ($context eq 'domain') { - my $dcdom = $env{'request.role.domain'}; - $loaditem->{'onload'} = "document.cu.coursedesc.value='';"; - $dc_setcourse_code = - &Apache::lonuserutils::dc_setcourse_js('cu','singleuser',$context); + if ((ref($permission) eq 'HASH') && ($permission->{'cusr'})) { + my $dcdom = $env{'request.role.domain'}; + $loaditem->{'onload'} = "document.cu.coursedesc.value='';"; + $dc_setcourse_code = + &Apache::lonuserutils::dc_setcourse_js('cu','singleuser',$context); + } } else { my $checkauth; if (($newuser) || (&Apache::lonnet::allowed('mau',$ccdomain))) { @@ -1037,7 +1987,8 @@ sub validation_javascript { if ($context eq 'course') { $nondc_setsection_code = &Apache::lonuserutils::setsections_javascript($formname,$groupslist, - undef,$checkauth); + undef,$checkauth, + $crstype); } if ($checkauth) { $nondc_setsection_code .= @@ -1048,139 +1999,238 @@ sub validation_javascript { $nondc_setsection_code,$groupslist); my ($jsback,$elements) = &crumb_utilities(); $js .= "\n". - ''; + ''."\n"; return $js; } sub display_existing_roles { - my ($r,$ccuname,$ccdomain,$inccourses) = @_; - my %rolesdump=&Apache::lonnet::dump('roles',$ccdomain,$ccuname); - # Build up table of user roles to allow revocation and re-enabling of roles. - my ($tmp) = keys(%rolesdump); - if ($tmp !~ /^(con_lost|error)/i) { - my $now=time; - my %lt=&Apache::lonlocal::texthash( + my ($r,$ccuname,$ccdomain,$inccourses,$context,$roledom,$crstype, + $showcredits,$statuses) = @_; + my $now=time; + my $showall = 1; + my ($showexpired,$showactive); + if ((ref($statuses) eq 'ARRAY') && (@{$statuses} > 0)) { + $showall = 0; + if (grep(/^expired$/,@{$statuses})) { + $showexpired = 1; + } + if (grep(/^active$/,@{$statuses})) { + $showactive = 1; + } + if ($showexpired && $showactive) { + $showall = 1; + } + } + my %lt=&Apache::lonlocal::texthash( 'rer' => "Existing Roles", 'rev' => "Revoke", 'del' => "Delete", 'ren' => "Re-Enable", 'rol' => "Role", 'ext' => "Extent", + 'crd' => "Credits", 'sta' => "Start", 'end' => "End", ); - my (%roletext,%sortrole,%roleclass,%rolepriv); - foreach my $area (sort { my $a1=join('_',(split('_',$a))[1,0]); - my $b1=join('_',(split('_',$b))[1,0]); - return $a1 cmp $b1; - } keys(%rolesdump)) { - next if ($area =~ /^rolesdef/); - my $envkey=$area; - my $role = $rolesdump{$area}; - my $thisrole=$area; - $area =~ s/\_\w\w$//; - my ($role_code,$role_end_time,$role_start_time) = - split(/_/,$role); + my (%rolesdump,%roletext,%sortrole,%roleclass,%rolepriv); + if ($context eq 'course' || $context eq 'author') { + my @roles = &Apache::lonuserutils::roles_by_context($context,1,$crstype); + my %roleshash = + &Apache::lonnet::get_my_roles($ccuname,$ccdomain,'userroles', + ['active','previous','future'],\@roles,$roledom,1); + foreach my $key (keys(%roleshash)) { + my ($start,$end) = split(':',$roleshash{$key}); + next if ($start eq '-1' || $end eq '-1'); + my ($rnum,$rdom,$role,$sec) = split(':',$key); + if ($context eq 'course') { + next unless (($rnum eq $env{'course.'.$env{'request.course.id'}.'.num'}) + && ($rdom eq $env{'course.'.$env{'request.course.id'}.'.domain'})); + } elsif ($context eq 'author') { + if ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$}) { + my ($audom,$auname) = ($1,$2); + next unless (($rnum eq $auname) && ($rdom eq $audom)); + } else { + next unless (($rnum eq $env{'user.name'}) && ($rdom eq $env{'request.role.domain'})); + } + } + my ($newkey,$newvalue,$newrole); + $newkey = '/'.$rdom.'/'.$rnum; + if ($sec ne '') { + $newkey .= '/'.$sec; + } + $newvalue = $role; + if ($role =~ /^cr/) { + $newrole = 'cr'; + } else { + $newrole = $role; + } + $newkey .= '_'.$newrole; + if ($start ne '' && $end ne '') { + $newvalue .= '_'.$end.'_'.$start; + } elsif ($end ne '') { + $newvalue .= '_'.$end; + } + $rolesdump{$newkey} = $newvalue; + } + } else { + %rolesdump=&Apache::lonnet::dump('roles',$ccdomain,$ccuname); + } + # Build up table of user roles to allow revocation and re-enabling of roles. + my ($tmp) = keys(%rolesdump); + return if ($tmp =~ /^(con_lost|error)/i); + foreach my $area (sort { my $a1=join('_',(split('_',$a))[1,0]); + my $b1=join('_',(split('_',$b))[1,0]); + return $a1 cmp $b1; + } keys(%rolesdump)) { + next if ($area =~ /^rolesdef/); + my $envkey=$area; + my $role = $rolesdump{$area}; + my $thisrole=$area; + $area =~ s/\_\w\w$//; + my ($role_code,$role_end_time,$role_start_time) = + split(/_/,$role); + my $active=1; + $active=0 if (($role_end_time) && ($now>$role_end_time)); + if ($active) { + next unless($showall || $showactive); + } else { + next unless($showall || $showexpired); + } # Is this a custom role? Get role owner and title. - my ($croleudom,$croleuname,$croletitle)= - ($role_code=~m{^cr/($match_domain)/($match_username)/(\w+)$}); - my $allowed=0; - my $delallowed=0; - my $sortkey=$role_code; - my $class='Unknown'; - if ($area =~ m{^/($match_domain)/($match_courseid)} ) { - $class='Course'; - my ($coursedom,$coursedir) = ($1,$2); - $sortkey.="\0$coursedom"; - # $1.'_'.$2 is the course id (eg. 103_12345abcef103l3). - my %coursedata= - &Apache::lonnet::coursedescription($1.'_'.$2); - my $carea; - if (defined($coursedata{'description'})) { - $carea=$coursedata{'description'}. - '
'.&mt('Domain').': '.$coursedom.(' 'x8). - &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$coursedir,$coursedom); - $sortkey.="\0".$coursedata{'description'}; - $class=$coursedata{'type'}; + my ($croleudom,$croleuname,$croletitle)= + ($role_code=~m{^cr/($match_domain)/($match_username)/(\w+)$}); + my $allowed=0; + my $delallowed=0; + my $sortkey=$role_code; + my $class='Unknown'; + my $credits=''; + my $csec; + if ($area =~ m{^/($match_domain)/($match_courseid)}) { + $class='Course'; + my ($coursedom,$coursedir) = ($1,$2); + my $cid = $1.'_'.$2; + # $1.'_'.$2 is the course id (eg. 103_12345abcef103l3). + next if ($envkey =~ m{^/$match_domain/$match_courseid/[A-Za-z0-9]+_gr$}); + my %coursedata= + &Apache::lonnet::coursedescription($cid); + if ($coursedir =~ /^$match_community$/) { + $class='Community'; + } + $sortkey.="\0$coursedom"; + my $carea; + if (defined($coursedata{'description'})) { + $carea=$coursedata{'description'}. + '
'.&mt('Domain').': '.$coursedom.(' 'x8). + &Apache::loncommon::syllabuswrapper(&mt('Syllabus'),$coursedir,$coursedom); + $sortkey.="\0".$coursedata{'description'}; + } else { + if ($class eq 'Community') { + $carea=&mt('Unavailable community').': '.$area; + $sortkey.="\0".&mt('Unavailable community').': '.$area; } else { $carea=&mt('Unavailable course').': '.$area; $sortkey.="\0".&mt('Unavailable course').': '.$area; } - $sortkey.="\0$coursedir"; - $inccourses->{$1.'_'.$2}=1; - if ((&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2)) || - (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) { - $allowed=1; - } - if ((&Apache::lonnet::allowed('dro',$1)) || - (&Apache::lonnet::allowed('dro',$ccdomain))) { - $delallowed=1; + } + $sortkey.="\0$coursedir"; + $inccourses->{$cid}=1; + if (($showcredits) && ($class eq 'Course') && ($role_code eq 'st')) { + my $defaultcredits = $coursedata{'internal.defaultcredits'}; + $credits = + &get_user_credits($ccuname,$ccdomain,$defaultcredits, + $coursedom,$coursedir); + if ($credits eq '') { + $credits = $defaultcredits; + } + } + if ((&Apache::lonnet::allowed('c'.$role_code,$coursedom.'/'.$coursedir)) || + (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) { + $allowed=1; + } + unless ($allowed) { + my $isowner = &Apache::lonuserutils::is_courseowner($cid,$coursedata{'internal.courseowner'}); + if ($isowner) { + if (($role_code eq 'co') && ($class eq 'Community')) { + $allowed = 1; + } elsif (($role_code eq 'cc') && ($class eq 'Course')) { + $allowed = 1; + } } + } + if ((&Apache::lonnet::allowed('dro',$coursedom)) || + (&Apache::lonnet::allowed('dro',$ccdomain))) { + $delallowed=1; + } # - custom role. Needs more info, too - if ($croletitle) { - if (&Apache::lonnet::allowed('ccr',$1.'/'.$2)) { - $allowed=1; - $thisrole.='.'.$role_code; - } + if ($croletitle) { + if (&Apache::lonnet::allowed('ccr',$coursedom.'/'.$coursedir)) { + $allowed=1; + $thisrole.='.'.$role_code; } - # Compute the background color based on $area - if ($area=~m{^/($match_domain)/($match_courseid)/(\w+)}) { - $carea.='
Section: '.$3; - $sortkey.="\0$3"; - if (!$allowed) { - if ($env{'request.course.sec'} eq $3) { - if (&Apache::lonnet::allowed('c'.$role_code,$1.'/'.$2.'/'.$3)) { - $allowed = 1; - } + } + if ($area=~m{^/($match_domain/$match_courseid/(\w+))}) { + $csec = $2; + $carea.='
'.&mt('Section: [_1]',$csec); + $sortkey.="\0$csec"; + if (!$allowed) { + if ($env{'request.course.sec'} eq $csec) { + if (&Apache::lonnet::allowed('c'.$role_code,$1)) { + $allowed = 1; } } } - $area=$carea; - } else { - $sortkey.="\0".$area; - # Determine if current user is able to revoke privileges - if ($area=~m{^/($match_domain)/}) { - if ((&Apache::lonnet::allowed('c'.$role_code,$1)) || - (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) { - $allowed=1; - } - if (((&Apache::lonnet::allowed('dro',$1)) || - (&Apache::lonnet::allowed('dro',$ccdomain))) && - ($role_code ne 'dc')) { - $delallowed=1; - } - } else { - if (&Apache::lonnet::allowed('c'.$role_code,'/')) { - $allowed=1; - } + } + $area=$carea; + } else { + $sortkey.="\0".$area; + # Determine if current user is able to revoke privileges + if ($area=~m{^/($match_domain)/}) { + if ((&Apache::lonnet::allowed('c'.$role_code,$1)) || + (&Apache::lonnet::allowed('c'.$role_code,$ccdomain))) { + $allowed=1; } - if ($role_code eq 'ca' || $role_code eq 'au') { - $class='Construction Space'; - } elsif ($role_code eq 'su') { - $class='System'; - } else { - $class='Domain'; + if (((&Apache::lonnet::allowed('dro',$1)) || + (&Apache::lonnet::allowed('dro',$ccdomain))) && + ($role_code ne 'dc')) { + $delallowed=1; } - } - if (($role_code eq 'ca') || ($role_code eq 'aa')) { - $area=~m{/($match_domain)/($match_username)}; - if (&Apache::lonuserutils::authorpriv($2,$1)) { + } else { + if (&Apache::lonnet::allowed('c'.$role_code,'/')) { $allowed=1; - } else { - $allowed=0; } } - my $row = ''; + if ($role_code eq 'ca' || $role_code eq 'au' || $role_code eq 'aa') { + $class='Authoring Space'; + } elsif ($role_code eq 'su') { + $class='System'; + } else { + $class='Domain'; + } + } + if (($role_code eq 'ca') || ($role_code eq 'aa')) { + $area=~m{/($match_domain)/($match_username)}; + if (&Apache::lonuserutils::authorpriv($2,$1)) { + $allowed=1; + } elsif (&Apache::lonuserutils::coauthorpriv($2,$1)) { + $allowed=1; + } else { + $allowed=0; + } + } + my $row = ''; + if ($showall) { $row.= ''; - my $active=1; - $active=0 if (($role_end_time) && ($now>$role_end_time)); if (($active) && ($allowed)) { $row.= ''; } else { if ($active) { - $row.=' '; + $row.=' '; } else { - $row.=&mt('expired or revoked'); + $row.=&mt('expired or revoked'); } } $row.=''; @@ -1195,71 +2245,115 @@ sub display_existing_roles { } else { $row.=' '; } - my $plaintext=''; - if (!$croletitle) { - $plaintext=&Apache::lonnet::plaintext($role_code,$class) - } else { - $plaintext= - "Customrole '$croletitle'
defined by $croleuname\@$croleudom"; - } - $row.= ''.$plaintext. - ''.$area. - ''.($role_start_time?localtime($role_start_time) - : ' ' ). - ''.($role_end_time ?localtime($role_end_time) - : ' ' ) - .""; - $sortrole{$sortkey}=$envkey; - $roletext{$envkey}=$row; - $roleclass{$envkey}=$class; - $rolepriv{$envkey}=$allowed; - #$r->print($row); - } # end of foreach (table building loop) - my $rolesdisplay = 0; - my %output = (); - foreach my $type ('Construction Space','Course','Group','Domain','System','Unknown') { - $output{$type} = ''; - foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) { - if ( ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/ ) && ($rolepriv{$sortrole{$which}}) ) { - $output{$type}.= - &Apache::loncommon::start_data_table_row(). - $roletext{$sortrole{$which}}. - &Apache::loncommon::end_data_table_row(); - } - } - unless($output{$type} eq '') { - $output{$type} = ''. - "".&mt($type)."". - $output{$type}; - $rolesdisplay = 1; - } - } - if ($rolesdisplay == 1) { - my $contextrole=''; - if ($env{'request.course.id'}) { - $contextrole = 'Existing Roles in this Course'; - } elsif ($env{'request.role'} =~ /^au\./) { - $contextrole = 'Existing Co-Author Roles in your Construction Space'; - } else { - $contextrole = 'Existing Roles in this Domain'; - } - $r->print(' -

'.$lt{'rer'}.'

'. -'
'.&mt($contextrole).'
'. + $row.= ''; + } + my $plaintext=''; + if (!$croletitle) { + $plaintext=&Apache::lonnet::plaintext($role_code,$class); + if (($showcredits) && ($credits ne '')) { + $plaintext .= '
'. + ''. + &mt('Credits: [_1]',$credits). + ''; + } + } else { + $plaintext= + &mt('Custom role [_1][_2]defined by [_3]', + '"'.$croletitle.'"', + '
', + $croleuname.':'.$croleudom); + } + $row.= ''.$plaintext.''. + ''.$area.''. + ''.($role_start_time?&Apache::lonlocal::locallocaltime($role_start_time) + : ' ' ).''. + ''.($role_end_time ?&Apache::lonlocal::locallocaltime($role_end_time) + : ' ' ).''; + $sortrole{$sortkey}=$envkey; + $roletext{$envkey}=$row; + $roleclass{$envkey}=$class; + if ($allowed) { + $rolepriv{$envkey}='edit'; + } else { + if ($context eq 'domain') { + if ((&Apache::lonnet::allowed('vur',$ccdomain)) && + ($envkey=~m{^/$ccdomain/})) { + $rolepriv{$envkey}='view'; + } + } elsif ($context eq 'course') { + if ((&Apache::lonnet::allowed('vcl',$env{'request.course.id'})) || + ($env{'request.course.sec'} && ($env{'request.course.sec'} eq $csec) && + &Apache::lonnet::allowed('vcl',$env{'request.course.id'}.'/'.$env{'request.course.sec'}))) { + $rolepriv{$envkey}='view'; + } + } + } + } # end of foreach (table building loop) + + my $rolesdisplay = 0; + my %output = (); + foreach my $type ('Authoring Space','Course','Community','Domain','System','Unknown') { + $output{$type} = ''; + foreach my $which (sort {uc($a) cmp uc($b)} (keys(%sortrole))) { + if ( ($roleclass{$sortrole{$which}} =~ /^\Q$type\E/ ) && ($rolepriv{$sortrole{$which}}) ) { + $output{$type}.= + &Apache::loncommon::start_data_table_row(). + $roletext{$sortrole{$which}}. + &Apache::loncommon::end_data_table_row(); + } + } + unless($output{$type} eq '') { + $output{$type} = ''. + "".&mt($type)."". + $output{$type}; + $rolesdisplay = 1; + } + } + if ($rolesdisplay == 1) { + my $contextrole=''; + if ($env{'request.course.id'}) { + if (&Apache::loncommon::course_type() eq 'Community') { + $contextrole = &mt('Existing Roles in this Community'); + } else { + $contextrole = &mt('Existing Roles in this Course'); + } + } elsif ($env{'request.role'} =~ /^au\./) { + $contextrole = &mt('Existing Co-Author Roles in your Authoring Space'); + } elsif ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)/$}) { + $contextrole = &mt('Existing Co-Author Roles in [_1] Authoring Space', + ''.$1.'_'.$2.''); + } else { + if ($showall) { + $contextrole = &mt('Existing Roles in this Domain'); + } elsif ($showactive) { + $contextrole = &mt('Unexpired Roles in this Domain'); + } elsif ($showexpired) { + $contextrole = &mt('Expired or Revoked Roles in this Domain'); + } + } + $r->print('
'. +'
'.$contextrole.''. &Apache::loncommon::start_data_table("LC_createuser"). -&Apache::loncommon::start_data_table_header_row(). -''.$lt{'rev'}.''.$lt{'ren'}.''.$lt{'del'}. -''.$lt{'rol'}.''.$lt{'ext'}. -''.$lt{'sta'}.''.$lt{'end'}.''. +&Apache::loncommon::start_data_table_header_row()); + if ($showall) { + $r->print( +''.$lt{'rev'}.''.$lt{'ren'}.''.$lt{'del'}.'' + ); + } elsif ($showexpired) { + $r->print(''.$lt{'rev'}.''); + } + $r->print( +''.$lt{'rol'}.''.$lt{'ext'}.''. +''.$lt{'sta'}.''.$lt{'end'}.''. &Apache::loncommon::end_data_table_header_row()); - foreach my $type ('Construction Space','Course','Group','Domain','System','Unknown') { - if ($output{$type}) { - $r->print($output{$type}."\n"); - } + foreach my $type ('Authoring Space','Course','Community','Domain','System','Unknown') { + if ($output{$type}) { + $r->print($output{$type}."\n"); } - $r->print(&Apache::loncommon::end_data_table()); } - } # End of check for keys in rolesdump + $r->print(&Apache::loncommon::end_data_table(). + '
'); + } return; } @@ -1269,15 +2363,27 @@ sub new_coauthor_roles { # # Co-Author # - if (&Apache::lonuserutils::authorpriv($env{'user.name'}, - $env{'request.role.domain'}) && - ($env{'user.name'} ne $ccuname || $env{'user.domain'} ne $ccdomain)) { + my ($cuname,$cudom); + if (($env{'request.role'} eq "au./$env{'user.domain'}/") || + ($env{'request.role'} eq "dc./$env{'user.domain'}/")) { + $cuname=$env{'user.name'}; + $cudom=$env{'request.role.domain'}; # No sense in assigning co-author role to yourself - $addrolesdisplay = 1; - my $cuname=$env{'user.name'}; - my $cudom=$env{'request.role.domain'}; + if ((&Apache::lonuserutils::authorpriv($cuname,$cudom)) && + ($env{'user.name'} ne $ccuname || $env{'user.domain'} ne $ccdomain)) { + $addrolesdisplay = 1; + } + } elsif ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$}) { + ($cudom,$cuname) = ($1,$2); + if ((&Apache::lonuserutils::coauthorpriv($cuname,$cudom)) && + ($env{'user.name'} ne $ccuname || $env{'user.domain'} ne $ccdomain) && + ($cudom ne $ccdomain || $cuname ne $ccuname)) { + $addrolesdisplay = 1; + } + } + if ($addrolesdisplay) { my %lt=&Apache::lonlocal::texthash( - 'cs' => "Construction Space", + 'cs' => "Authoring Space", 'act' => "Activate", 'rol' => "Role", 'ext' => "Extent", @@ -1328,14 +2434,25 @@ sub new_coauthor_roles { ''); } elsif (($env{'user.name'} eq $ccuname) && ($env{'user.domain'} eq $ccdomain)) { - $r->print(&mt('Assigning yourself a co-author or assistant co-author role in your own author area in Construction Space is not permitted')); + $r->print(&mt('Assigning yourself a co-author or assistant co-author role in your own author area in Authoring Space is not permitted')); + } + } elsif ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$}) { + if (!(&Apache::lonuserutils::coauthorpriv($2,$1))) { + $r->print(''. + &mt('You do not have privileges to assign co-author roles.'). + ''); + } elsif (($env{'user.name'} eq $ccuname) && + ($env{'user.domain'} eq $ccdomain)) { + $r->print(&mt('Assigning yourself a co-author or assistant co-author role in an author area in Authoring Space in which you already have a co-author role is not permitted')); + } elsif (($cudom eq $ccdomain) && ($cuname eq $ccuname)) { + $r->print(&mt("Assigning a co-author or assistant co-author role to an Authoring Space's author is not permitted")); } } return $addrolesdisplay;; } sub new_domain_roles { - my ($r) = @_; + my ($r,$ccdomain) = @_; my $addrolesdisplay = 0; # # Domain level @@ -1349,9 +2466,21 @@ sub new_domain_roles { &mt('Extent').''. ''.&mt('Start').''.&mt('End').''. &Apache::loncommon::end_data_table_header_row(); + my @allroles = &Apache::lonuserutils::roles_by_context('domain'); + my $uprimary = &Apache::lonnet::domain($env{'request.role.domain'},'primary'); + my $uintdom = &Apache::lonnet::internet_dom($uprimary); foreach my $thisdomain (sort(&Apache::lonnet::all_domains())) { - foreach my $role ('dc','li','dg','au','sc') { + foreach my $role (@allroles) { + next if ($role eq 'ad'); + next if (($role eq 'au') && ($ccdomain ne $thisdomain)); if (&Apache::lonnet::allowed('c'.$role,$thisdomain)) { + if ($role eq 'dc') { + unless ($thisdomain eq $env{'request.role.domain'}) { + my $domprim = &Apache::lonnet::domain($thisdomain,'primary'); + my $intdom = &Apache::lonnet::internet_dom($domprim); + next unless ($uintdom eq $intdom); + } + } my $plrole=&Apache::lonnet::plaintext($role); my %lt=&Apache::lonlocal::texthash( 'ssd' => "Set Start Date", @@ -1382,26 +2511,28 @@ sub new_domain_roles { } sub user_authentication { - my ($ccuname,$ccdomain,$formname) = @_; + my ($ccuname,$ccdomain,$formname,$crstype,$permission) = @_; my $currentauth=&Apache::lonnet::queryauthenticate($ccuname,$ccdomain); my $outcome; + my %lt=&Apache::lonlocal::texthash( + 'err' => "ERROR", + 'uuas' => "This user has an unrecognized authentication scheme", + 'adcs' => "Please alert a domain coordinator of this situation", + 'sldb' => "Please specify login data below", + 'ld' => "Login Data" + ); # Check for a bad authentication type - if ($currentauth !~ /^(krb4|krb5|unix|internal|localauth):/) { + if ($currentauth !~ /^(krb4|krb5|unix|internal|localauth|lti):/) { # bad authentication scheme - my %lt=&Apache::lonlocal::texthash( - 'err' => "ERROR", - 'uuas' => "This user has an unrecognized authentication scheme", - 'adcs' => "Please alert a domain coordinator of this situation", - 'sldb' => "Please specify login data below", - 'ld' => "Login Data" - ); if (&Apache::lonnet::allowed('mau',$ccdomain)) { &initialize_authen_forms($ccdomain,$formname); my $choices = &Apache::lonuserutils::set_login($ccdomain,$authformkrb,$authformint,$authformloc); $outcome = < +// $lt{'err'}: $lt{'uuas'} ($currentauth). $lt{'sldb'}. @@ -1418,25 +2549,23 @@ $lt{'uuas'} ($currentauth). $lt{'adcs'}. ENDBADAUTH } } else { # Authentication type is valid + &initialize_authen_forms($ccdomain,$formname,$currentauth,'modifyuser'); my ($authformcurrent,$can_modify,@authform_others) = &modify_login_block($ccdomain,$currentauth); if (&Apache::lonnet::allowed('mau',$ccdomain)) { # Current user has login modification privileges - my %lt=&Apache::lonlocal::texthash ( - 'ld' => "Login Data", - 'ccld' => "Change Current Login Data", - 'enld' => "Enter New Login Data" - ); $outcome = ''."\n". '

'.$lt{'ld'}.'

'. &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_row(). ''.$authformnop; - if ($can_modify) { + if (($can_modify) && (&Apache::lonnet::allowed('mau',$ccdomain))) { $outcome .= ''."\n". &Apache::loncommon::end_data_table_row(). &Apache::loncommon::start_data_table_row(). @@ -1446,14 +2575,79 @@ ENDBADAUTH $outcome .= ' ('.$authformcurrent.')'. &Apache::loncommon::end_data_table_row()."\n"; } - foreach my $item (@authform_others) { - $outcome .= &Apache::loncommon::start_data_table_row(). - ''.$item.''. - &Apache::loncommon::end_data_table_row()."\n"; + if (&Apache::lonnet::allowed('mau',$ccdomain)) { + foreach my $item (@authform_others) { + $outcome .= &Apache::loncommon::start_data_table_row(). + ''.$item.''. + &Apache::loncommon::end_data_table_row()."\n"; + } } $outcome .= &Apache::loncommon::end_data_table(); } else { - if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) { + if (($currentauth =~ /^internal:/) && + (&Apache::lonuserutils::can_change_internalpass($ccuname,$ccdomain,$crstype,$permission))) { + $outcome = <<"ENDJS"; + +ENDJS + + $outcome .= '

'.$lt{'ld'}.'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_row(). + ''.&mt('Internally authenticated').'
'.&mt("Change user's password?"). + ''.(' 'x2). + ''. + ''. + &Apache::loncommon::end_data_table_row(). + &Apache::loncommon::end_data_table(); + } + if (&Apache::lonnet::allowed('udp',$ccdomain)) { + # Current user has rights to view domain preferences for user's domain + my $result; + if ($currentauth =~ /^krb(4|5):([^:]*)$/) { + my ($krbver,$krbrealm) = ($1,$2); + if ($krbrealm eq '') { + $result = &mt('Currently Kerberos authenticated, Version [_1].',$krbver); + } else { + $result = &mt('Currently Kerberos authenticated with domain [_1] Version [_2].', + $krbrealm,$krbver); + } + } elsif ($currentauth =~ /^internal:/) { + $result = &mt('Currently internally authenticated.'); + } elsif ($currentauth =~ /^localauth:/) { + $result = &mt('Currently using local (institutional) authentication.'); + } elsif ($currentauth =~ /^unix:/) { + $result = &mt('Currently Filesystem Authenticated.'); + } elsif ($currentauth =~ /^lti:/) { + $result = &mt('Currently LTI authenticated.'); + } + $outcome = '

'.$lt{'ld'}.'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_row(). + ''.$result.''. + &Apache::loncommon::end_data_table_row()."\n". + &Apache::loncommon::end_data_table(); + } elsif (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) { my %lt=&Apache::lonlocal::texthash( 'ccld' => "Change Current Login Data", 'yodo' => "You do not have privileges to modify the authentication configuration for this user.", @@ -1484,6 +2678,9 @@ sub modify_login_block { if ($can_assign{'loc'}) { push(@authform_others,$authformloc); } + if ($can_assign{'lti'}) { + push(@authform_others,$authformlti); + } if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { $show_override_msg = 1; } @@ -1495,6 +2692,9 @@ sub modify_login_block { if ($can_assign{'loc'}) { push(@authform_others,$authformloc); } + if ($can_assign{'lti'}) { + push(@authform_others,$authformlti); + } if ($can_assign{'int'}) { $show_override_msg = 1; } @@ -1509,6 +2709,9 @@ sub modify_login_block { if ($can_assign{'loc'}) { push(@authform_others,$authformloc); } + if ($can_assign{'lti'}) { + push(@authform_others,$authformlti); + } if ($can_assign{'fsys'}) { $show_override_msg = 1; } @@ -1520,9 +2723,23 @@ sub modify_login_block { if ($can_assign{'int'}) { push(@authform_others,$authformint); } + if ($can_assign{'lti'}) { + push(@authform_others,$authformlti); + } if ($can_assign{'loc'}) { $show_override_msg = 1; } + } elsif ($currentauth=~/^lti:/) { + $authformcurrent=$authformlti; + if (($can_assign{'krb4'}) || ($can_assign{'krb5'})) { + push(@authform_others,$authformkrb); + } + if ($can_assign{'int'}) { + push(@authform_others,$authformint); + } + if ($can_assign{'loc'}) { + push(@authform_others,$authformloc); + } } if ($show_override_msg) { $authformcurrent = ' - - - - - - -END - if ($showinststatus) { - $r->print(" - \n"); - } - if ($showrequestcourses) { - foreach my $item (@requestcourses) { - $r->print(" - \n"); - } - } - if ($showquota) { - $r->print(" - \n"); - } - if ($showtools) { - foreach my $item (@usertools) { - $r->print(" - \n"); - } - } - $r->print(&Apache::loncommon::end_data_table_header_row(). - &Apache::loncommon::start_data_table_row()); - $r->print(<<"END"); - - - - - - - -END - if ($showinststatus) { - $r->print(" - \n"); - } - if ($showrequestcourses) { - foreach my $item (@requestcourses) { - $r->print(" - \n"); - } - } - if ($showquota) { - $r->print(" - \n"); - } - if ($showtools) { - foreach my $item (@usertools) { - $r->print(" - \n"); - } - } - $r->print(&Apache::loncommon::end_data_table_row(). - &Apache::loncommon::start_data_table_row()); - $r->print(<<"END"); - - - - - - - -END - if ($showinststatus) { - $r->print(" - \n"); - } - if ($showrequestcourses) { - foreach my $item (@requestcourses) { - $r->print(" - \n"); - } - } - if ($showquota) { - $r->print(" - \n"); - } - if ($showtools) { - foreach my $item (@usertools) { - $r->print(" - \n"); - } - } - $r->print(&Apache::loncommon::end_data_table_row(). - &Apache::loncommon::end_data_table().'
'); + &display_userinfo($r,1,\@disporder,\%canshow,\@requestcourses, + \@usertools,\@requestauthor,\%userenv,\%changed,\%namechanged, + \%oldsettings, \%oldsettingstext,\%newsettings, + \%newsettingstext); if ($env{'form.cid'} ne $userenv{'id'}) { &Apache::lonnet::idput($env{'form.ccdomain'}, - ($env{'form.ccuname'} => $env{'form.cid'})); + {$env{'form.ccuname'} => $env{'form.cid'}},$uhome,'ids'); if (($recurseid) && (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'}))) { my $idresult = @@ -2429,52 +3892,20 @@ END &Apache::lonnet::appenv(\%newenvhash); } } else { # error occurred - $r->print(''.&mt('Unable to successfully change environment for').' '. - $env{'form.ccuname'}.' '.&mt('in domain').' '. - $env{'form.ccdomain'}.'
'); + $r->print( + '

' + .&mt('Unable to successfully change environment for [_1] in domain [_2].', + '"'.$env{'form.ccuname'}.'"', + '"'.$env{'form.ccdomain'}.'"') + .'

'); } - } else { # End of if ($env ... ) logic + } else { # End of if ($env ... ) logic # They did not want to change the users name, quota, tool availability, # or ability to request creation of courses, # but we can still tell them what the name and quota and availabilities are - my %lt=&Apache::lonlocal::texthash( - 'id' => "Student/Employee ID", - 'mail' => "Permanent e-mail address", - 'disk' => "Disk space allocated to user's portfolio files", - 'blog' => "Blog Availability", - 'aboutme' => "Personal Information Page Availability", - 'portfolio' => "Portfolio Availability", - 'official' => "Can Request Official Courses", - 'unofficial' => "Can Request Unofficial Course", - 'inststatus' => "Affiliation", - ); - $r->print(<<"END"); -

$userenv{'firstname'} $userenv{'middlename'} $userenv{'lastname'} $userenv{'generation'} -END - if ($userenv{'permanentemail'} ne '') { - $r->print('
['.$lt{'mail'}.': '. - $userenv{'permanentemail'}.']'); - } - if ($showinststatus) { - $r->print('
['.$lt{'inststatus'}.': '.$oldinststatuses.']'); - } - if ($showrequestcourses) { - foreach my $item (@requestcourses) { - $r->print('
['.$lt{$item}.': '.$newaccess{$item}.' '. - $newaccesstext{$item}.']'."\n"); - } - } - if ($showtools) { - foreach my $item (@usertools) { - $r->print('
['.$lt{$item}.': '.$newaccess{$item}.' '. - $newaccesstext{$item}.']'."\n"); - } - } - if ($showquota) { - $r->print('
['.$lt{'disk'}.': '.$oldportfolioquota.' Mb '. - $olddefquotatext.']'); - } - $r->print('

'); + &display_userinfo($r,undef,\@disporder,\%canshow,\@requestcourses, + \@usertools,\@requestauthor,\%userenv,\%changed,\%namechanged,\%oldsettings, + \%oldsettingstext,\%newsettings,\%newsettingstext); } if (@mod_disallowed) { my ($rolestr,$contextname); @@ -2484,9 +3915,9 @@ END $rolestr = &mt('No roles'); } if ($context eq 'course') { - $contextname = &mt('course'); + $contextname = 'course'; } elsif ($context eq 'author') { - $contextname = &mt('co-author'); + $contextname = 'co-author'; } $r->print(&mt('The following fields were not updated: ').'
    '); my %fieldtitles = &Apache::loncommon::personal_data_fieldtitles(); @@ -2495,9 +3926,9 @@ END } $r->print('
'); if (@mod_disallowed == 1) { - $r->print(&mt("You do not have the authority to change this field given the user's current set of active/future [_1] roles:",$contextname)); + $r->print(&mt("You do not have the authority to change this field given the user's current set of active/future $contextname roles:")); } else { - $r->print(&mt("You do not have the authority to change these fields given the user's current set of active/future [_1] roles:",$contextname)); + $r->print(&mt("You do not have the authority to change these fields given the user's current set of active/future $contextname roles:")); } my $helplink = 'javascript:helpMenu('."'display'".')'; $r->print(''.$rolestr.'
' @@ -2510,13 +3941,21 @@ END .&Apache::lonuserutils::print_namespacing_alerts($env{'form.ccdomain'},\%alerts,\%curr_rules) .''); } + &Apache::lonhtmlcommon::Close_PrgWin($r,\%prog_state); if ($env{'form.action'} eq 'singlestudent') { - &enroll_single_student($r,$uhome,$amode,$genpwd,$now,$newuser,$context); - $r->print('

'. - &mt('Enroll Another Student').'

'); + &enroll_single_student($r,$uhome,$amode,$genpwd,$now,$newuser,$context, + $crstype,$showcredits,$defaultcredits); + my $linktext = ($crstype eq 'Community' ? + &mt('Enroll Another Member') : &mt('Enroll Another Student')); + $r->print( + &Apache::lonhtmlcommon::actionbox([ + '' + .($crstype eq 'Community' ? + &mt('Enroll Another Member') : &mt('Enroll Another Student')) + .''])); } else { - my @rolechanges = &update_roles($r,$context); - if ($namechanged) { + my @rolechanges = &update_roles($r,$context,$showcredits); + if (keys(%namechanged) > 0) { if ($context eq 'course') { if (@userroles > 0) { if ((@rolechanges == 0) || @@ -2536,13 +3975,166 @@ END if ($env{'form.popup'}) { $r->print('

'.&mt('Close window').'

'); } else { - $r->print('

' - .&mt('Modify this user: [_1]',''.$env{'form.ccuname'}.':'.$env{'form.ccdomain'}.' ('.$userinfo.')').'' - .(' 'x5).'' - .&mt('Create/Modify Another User').'

'); + $r->print('
'.&Apache::lonhtmlcommon::actionbox(['' + .&mt('Modify this user: [_1]',''.$env{'form.ccuname'}.':'.$env{'form.ccdomain'}.' ('.$userinfo.')').'', + ''.&mt('Create/Modify Another User').''])); } } - $r->print(&Apache::loncommon::end_page()); +} + +sub display_userinfo { + my ($r,$changed,$order,$canshow,$requestcourses,$usertools,$requestauthor, + $userenv,$changedhash,$namechangedhash,$oldsetting,$oldsettingtext, + $newsetting,$newsettingtext) = @_; + return unless (ref($order) eq 'ARRAY' && + ref($canshow) eq 'HASH' && + ref($requestcourses) eq 'ARRAY' && + ref($requestauthor) eq 'ARRAY' && + ref($usertools) eq 'ARRAY' && + ref($userenv) eq 'HASH' && + ref($changedhash) eq 'HASH' && + ref($oldsetting) eq 'HASH' && + ref($oldsettingtext) eq 'HASH' && + ref($newsetting) eq 'HASH' && + ref($newsettingtext) eq 'HASH'); + my %lt=&Apache::lonlocal::texthash( + 'ui' => 'User Information', + 'uic' => 'User Information Changed', + 'firstname' => 'First Name', + 'middlename' => 'Middle Name', + 'lastname' => 'Last Name', + 'generation' => 'Generation', + 'id' => 'Student/Employee ID', + 'permanentemail' => 'Permanent e-mail address', + 'portfolioquota' => 'Disk space allocated to portfolio files', + 'authorquota' => 'Disk space allocated to Authoring Space', + 'blog' => 'Blog Availability', + 'webdav' => 'WebDAV Availability', + 'aboutme' => 'Personal Information Page Availability', + 'portfolio' => 'Portfolio Availability', + 'portaccess' => 'Portfolio Shareable', + 'timezone' => 'Can set own Time Zone', + 'official' => 'Can Request Official Courses', + 'unofficial' => 'Can Request Unofficial Courses', + 'community' => 'Can Request Communities', + 'textbook' => 'Can Request Textbook Courses', + 'placement' => 'Can Request Placement Tests', + 'lti' => 'Can Request LTI Courses', + 'requestauthor' => 'Can Request Author Role', + 'inststatus' => "Affiliation", + 'prvs' => 'Previous Value:', + 'chto' => 'Changed To:', + 'editors' => "Available Editors in Authoring Space", + 'managers' => "Co-authors who can add/revoke co-authors", + 'edit' => 'Standard editor (Edit)', + 'xml' => 'Text editor (EditXML)', + 'daxe' => 'Daxe editor (Daxe)', + ); + if ($changed) { + $r->print('

'.$lt{'uic'}.'

'. + &Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row()); + $r->print("\n"); + $r->print(''); + $r->print(''); + $r->print(&Apache::loncommon::end_data_table_header_row()); + my @userinfo = ('firstname','middlename','lastname','generation','permanentemail','id'); + + foreach my $item (@userinfo) { + my $value = $env{'form.c'.$item}; + #show changes only: + unless ($value eq $userenv->{$item}){ + $r->print(&Apache::loncommon::start_data_table_row()); + $r->print("\n"); + $r->print("\n"); + $r->print("\n"); + $r->print(&Apache::loncommon::end_data_table_row()); + } + } + foreach my $entry (@{$order}) { + if ($canshow->{$entry}) { + if (($entry eq 'requestcourses') || ($entry eq 'reqcrsotherdom') || + ($entry eq 'requestauthor') || ($entry eq 'authordefaults')) { + my @items; + if ($entry eq 'requestauthor') { + @items = ($entry); + } elsif ($entry eq 'authordefaults') { + @items = ('webdav','managers','editors'); + } else { + @items = @{$requestcourses}; + } + foreach my $item (@items) { + if (($newsetting->{$item} ne $oldsetting->{$item}) || + ($newsettingtext->{$item} ne $oldsettingtext->{$item})) { + $r->print(&Apache::loncommon::start_data_table_row()."\n"); + $r->print("\n\n"); + $r->print(&Apache::loncommon::end_data_table_row()."\n"); + } + } + } elsif ($entry eq 'tools') { + foreach my $item (@{$usertools}) { + if ($newsetting->{$item} ne $oldsetting->{$item}) { + $r->print(&Apache::loncommon::start_data_table_row()."\n"); + $r->print("\n"); + $r->print("\n"); + $r->print("\n"); + $r->print(&Apache::loncommon::end_data_table_row()."\n"); + } + } + } elsif ($entry eq 'quota') { + if ((ref($oldsetting->{$entry}) eq 'HASH') && (ref($oldsettingtext->{$entry}) eq 'HASH') && + (ref($newsetting->{$entry}) eq 'HASH') && (ref($newsettingtext->{$entry}) eq 'HASH')) { + foreach my $name ('portfolio','author') { + if ($newsetting->{$entry}->{$name} ne $oldsetting->{$entry}->{$name}) { + $r->print(&Apache::loncommon::start_data_table_row()."\n"); + $r->print("\n"); + $r->print("\n"); + $r->print("\n"); + $r->print(&Apache::loncommon::end_data_table_row()."\n"); + } + } + } + } else { + if ($newsetting->{$entry} ne $oldsetting->{$entry}) { + $r->print(&Apache::loncommon::start_data_table_row()."\n"); + $r->print("\n"); + $r->print("\n"); + $r->print("\n"); + $r->print(&Apache::loncommon::end_data_table_row()."\n"); + } + } + } + } + $r->print(&Apache::loncommon::end_data_table().'
'); + } else { + $r->print('

'.$lt{'ui'}.'

'. + '

'.&mt('No changes made to user information').'

'); + } + return; } sub tool_changes { @@ -2554,32 +4146,300 @@ sub tool_changes { (ref($newaccess) eq 'HASH') && (ref($newaccesstext) eq 'HASH'))) { return; } + my %reqdisplay = &requestchange_display(); + if ($context eq 'reqcrsotherdom') { + my @options = ('approval','validate','autolimit'); + my $optregex = join('|',@options); + my $cdom = $env{'request.role.domain'}; + foreach my $tool (@{$usertools}) { + $oldaccesstext->{$tool} = &mt("availability set to 'off'"); + $newaccesstext->{$tool} = $oldaccesstext->{$tool}; + $changeHash->{$context.'.'.$tool} = $userenv->{$context.'.'.$tool}; + my ($newop,$limit); + if ($env{'form.'.$context.'_'.$tool}) { + $newop = $env{'form.'.$context.'_'.$tool}; + if ($newop eq 'autolimit') { + $limit = $env{'form.'.$context.'_'.$tool.'_limit'}; + $limit =~ s/\D+//g; + $newop .= '='.$limit; + } + } + if ($userenv->{$context.'.'.$tool} eq '') { + if ($newop) { + $changed->{$tool}=&tool_admin($tool,$cdom.':'.$newop, + $changeHash,$context); + if ($changed->{$tool}) { + if ($newop =~ /^autolimit/) { + if ($limit) { + $newaccesstext->{$tool} = &mt('available with automatic approval, up to limit of [quant,_1,request] per user',$limit); + } else { + $newaccesstext->{$tool} = &mt('available with automatic approval (unlimited)'); + } + } else { + $newaccesstext->{$tool} = $reqdisplay{$newop}; + } + } else { + $newaccesstext->{$tool} = $oldaccesstext->{$tool}; + } + } + } else { + my @curr = split(',',$userenv->{$context.'.'.$tool}); + my @new; + my $changedoms; + foreach my $req (@curr) { + if ($req =~ /^\Q$cdom\E\:($optregex\=?\d*)$/) { + my $oldop = $1; + if ($oldop =~ /^autolimit=(\d*)/) { + my $limit = $1; + if ($limit) { + $oldaccesstext->{$tool} = &mt('available with automatic approval, up to limit of [quant,_1,request] per user',$limit); + } else { + $oldaccesstext->{$tool} = &mt('available with automatic approval (unlimited)'); + } + } else { + $oldaccesstext->{$tool} = $reqdisplay{$oldop}; + } + if ($oldop ne $newop) { + $changedoms = 1; + foreach my $item (@curr) { + my ($reqdom,$option) = split(':',$item); + unless ($reqdom eq $cdom) { + push(@new,$item); + } + } + if ($newop) { + push(@new,$cdom.':'.$newop); + } + @new = sort(@new); + } + last; + } + } + if ((!$changedoms) && ($newop)) { + $changedoms = 1; + @new = sort(@curr,$cdom.':'.$newop); + } + if ($changedoms) { + my $newdomstr; + if (@new) { + $newdomstr = join(',',@new); + } + $changed->{$tool}=&tool_admin($tool,$newdomstr,$changeHash, + $context); + if ($changed->{$tool}) { + if ($env{'form.'.$context.'_'.$tool}) { + if ($env{'form.'.$context.'_'.$tool} eq 'autolimit') { + my $limit = $env{'form.'.$context.'_'.$tool.'_limit'}; + $limit =~ s/\D+//g; + if ($limit) { + $newaccesstext->{$tool} = &mt('available with automatic approval, up to limit of [quant,_1,request] per user',$limit); + } else { + $newaccesstext->{$tool} = &mt('available with automatic approval (unlimited)'); + } + } else { + $newaccesstext->{$tool} = $reqdisplay{$env{'form.'.$context.'_'.$tool}}; + } + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } + } + } + } + return; + } + my %tooldesc = &Apache::lonlocal::texthash( + 'edit' => 'Standard editor (Edit)', + 'xml' => 'Text editor (EditXML)', + 'daxe' => 'Daxe editor (Daxe)', + ); foreach my $tool (@{$usertools}) { - if ($userenv->{$context.'.'.$tool} ne '') { + my ($newval,$limit,$envkey); + $envkey = $context.'.'.$tool; + if ($context eq 'requestcourses') { + $newval = $env{'form.crsreq_'.$tool}; + if ($newval eq 'autolimit') { + $limit = $env{'form.crsreq_'.$tool.'_limit'}; + $limit =~ s/\D+//g; + $newval .= '='.$limit; + } + } elsif ($context eq 'requestauthor') { + $newval = $env{'form.'.$context}; + $envkey = $context; + } elsif ($context eq 'authordefaults') { + if ($tool eq 'editors') { + $envkey = 'authoreditors'; + if ($env{'form.customeditors'} == 1) { + my @editors; + my @posseditors = &Apache::loncommon::get_env_multiple('form.custom_editor'); + if (@posseditors) { + foreach my $editor (@posseditors) { + if (grep(/^\Q$editor\E$/,@posseditors)) { + unless (grep(/^\Q$editor\E$/,@editors)) { + push(@editors,$editor); + } + } + } + } + if (@editors) { + $newval = join(',',(sort(@editors))); + } + } + } elsif ($tool eq 'managers') { + $envkey = 'authormanagers'; + my @possibles = &Apache::loncommon::get_env_multiple('form.custommanagers'); + if (@possibles) { + my %ca_roles = &Apache::lonnet::get_my_roles($env{'form.ccuname'},$env{'form.ccdomain'}, + undef,['active','future'],['ca']); + if (keys(%ca_roles)) { + my @custommanagers; + foreach my $user (@possibles) { + if ($user =~ /^($match_username):($match_domain)$/) { + if (exists($ca_roles{$user.':ca'})) { + unless ($user eq $env{'form.ccuname'}.':'.$env{'form.ccdomain'}) { + push(@custommanagers,$user); + } + } + } + } + if (@custommanagers) { + $newval = join(',',sort(@custommanagers)); + } + } + } + } elsif ($tool eq 'webdav') { + $envkey = 'tools.webdav'; + $newval = $env{'form.'.$context.'_'.$tool}; + } + } else { + $newval = $env{'form.'.$context.'_'.$tool}; + } + if ($userenv->{$envkey} ne '') { $oldaccess->{$tool} = &mt('custom'); - if ($userenv->{$context.'.'.$tool}) { - $oldaccesstext->{$tool} = &mt("availability set to 'on'"); + if (($context eq 'requestcourses') || ($context eq 'requestauthor')) { + if ($userenv->{$envkey} =~ /^autolimit=(\d*)$/) { + my $currlimit = $1; + if ($currlimit eq '') { + $oldaccesstext->{$tool} = &mt('available with automatic approval (unlimited)'); + } else { + $oldaccesstext->{$tool} = &mt('available with automatic approval, up to limit of [quant,_1,request] per user',$currlimit); + } + } elsif ($userenv->{$envkey}) { + $oldaccesstext->{$tool} = $reqdisplay{$userenv->{$envkey}}; + } else { + $oldaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } elsif ($context eq 'authordefaults') { + if ($tool eq 'managers') { + if ($userenv->{$envkey} eq '') { + $oldaccesstext->{$tool} = &mt('Only author may manage co-author roles'); + } else { + my $managers = $userenv->{$envkey}; + $managers =~ s/,/, /g; + $oldaccesstext->{$tool} = $managers; + } + } elsif ($tool eq 'editors') { + $oldaccesstext->{$tool} = &mt('can use: [_1]', + join(', ', map { $tooldesc{$_} } split(/,/,$userenv->{$envkey}))); + } elsif ($tool eq 'webdav') { + if ($userenv->{$envkey}) { + $oldaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $oldaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } } else { - $oldaccesstext->{$tool} = &mt("availability set to 'off'"); + if ($userenv->{$envkey}) { + $oldaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $oldaccesstext->{$tool} = &mt("availability set to 'off'"); + } } - $changeHash->{$context.'.'.$tool} = $userenv->{$context.'.'.$tool}; - if ($env{'form.custom'.$tool} == 1) { - if ($env{'form.'.$context.'_'.$tool} ne $userenv->{$context.'.'.$tool}) { - $changed->{$tool} = &tool_admin($tool,$env{'form.'.$context.'_'.$tool}, - $changeHash,$context); + $changeHash->{$envkey} = $userenv->{$envkey}; + if (($env{'form.custom'.$tool} == 1) || + (($context eq 'authordefaults') && ($tool eq 'managers') && ($newval ne ''))) { + if ($newval ne $userenv->{$envkey}) { + $changed->{$tool} = &tool_admin($tool,$newval,$changeHash, + $context); if ($changed->{$tool}) { $newaccess->{$tool} = &mt('custom'); - if ($env{'form.'.$context.'_'.$tool}) { - $newaccesstext->{$tool} = &mt("availability set to 'on'"); + if (($context eq 'requestcourses') || ($context eq 'requestauthor')) { + if ($newval =~ /^autolimit/) { + if ($limit) { + $newaccesstext->{$tool} = &mt('available with automatic approval, up to limit of [quant,_1,request] per user',$limit); + } else { + $newaccesstext->{$tool} = &mt('available with automatic approval (unlimited)'); + } + } elsif ($newval) { + $newaccesstext->{$tool} = $reqdisplay{$newval}; + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } elsif ($context eq 'authordefaults') { + if ($tool eq 'editors') { + $newaccesstext->{$tool} = &mt('can use: [_1]', + join(', ', map { $tooldesc{$_} } split(/,/,$changeHash->{$envkey}))); + } elsif ($tool eq 'managers') { + if ($changeHash->{$envkey} eq '') { + $newaccesstext->{$tool} = &mt('Only author may manage co-author roles'); + } else { + my $managers = $changeHash->{$envkey}; + $managers =~ s/,/, /g; + $newaccesstext->{$tool} = $managers; + } + } elsif ($tool eq 'webdav') { + if ($newval) { + $newaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } } else { - $newaccesstext->{$tool} = &mt("availability set to 'off'"); + if ($newval) { + $newaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } } } else { $newaccess->{$tool} = $oldaccess->{$tool}; - if ($userenv->{$context.'.'.$tool}) { - $newaccesstext->{$tool} = &mt("availability set to 'on'"); + if (($context eq 'requestcourses') || ($context eq 'requestauthor')) { + if ($userenv->{$envkey} =~ /^autolimit/) { + if ($limit) { + $newaccesstext->{$tool} = &mt('available with automatic approval, up to limit of [quant,_1,request] per user',$limit); + } else { + $newaccesstext->{$tool} = &mt('available with automatic approval (unlimited)'); + } + } elsif ($userenv->{$envkey}) { + $newaccesstext->{$tool} = $reqdisplay{$userenv->{$envkey}}; + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } elsif ($context eq 'authordefaults') { + if ($tool eq 'editors') { + $newaccesstext->{$tool} = &mt('can use: [_1]', + join(', ', map { $tooldesc{$_} } split(/,/,$userenv->{$envkey}))); + } elsif ($tool eq 'managers') { + if ($userenv->{$envkey} eq '') { + $newaccesstext->{$tool} = &mt('Only author may manage co-author roles'); + } else { + my $managers = $userenv->{$envkey}; + $managers =~ s/,/, /g; + $newaccesstext->{$tool} = $managers; + } + } elsif ($tool eq 'webdav') { + if ($userenv->{$envkey}) { + $newaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } } else { - $newaccesstext->{$tool} = &mt("availability set to 'off'"); + if ($userenv->{$context.'.'.$tool}) { + $newaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } } } } else { @@ -2592,24 +4452,91 @@ sub tool_changes { $newaccess->{$tool} = &mt('default'); } else { $newaccess->{$tool} = $oldaccess->{$tool}; - if ($userenv->{$context.'.'.$tool}) { - $newaccesstext->{$tool} = &mt("availability set to 'on'"); + if (($context eq 'requestcourses') || ($context eq 'requestauthor')) { + if ($newval =~ /^autolimit/) { + if ($limit) { + $newaccesstext->{$tool} = &mt('available with automatic approval, up to limit of [quant,_1,request] per user',$limit); + } else { + $newaccesstext->{$tool} = &mt('available with automatic approval (unlimited)'); + } + } elsif ($newval) { + $newaccesstext->{$tool} = $reqdisplay{$newval}; + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } elsif ($context eq 'authordefaults') { + if ($tool eq 'editors') { + $newaccesstext->{$tool} = &mt('can use: [_1]', + join(', ', map { $tooldesc{$_} } split(/,/,$newval))); + } elsif ($tool eq 'managers') { + if ($newval eq '') { + $newaccesstext->{$tool} = &mt('Only author may manage co-author roles'); + } else { + my $managers = $newval; + $managers =~ s/,/, /g; + $newaccesstext->{$tool} = $managers; + } + } elsif ($tool eq 'webdav') { + if ($userenv->{$envkey}) { + $newaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } } else { - $newaccesstext->{$tool} = &mt("availability set to 'off'"); + if ($userenv->{$context.'.'.$tool}) { + $newaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } } } } } else { $oldaccess->{$tool} = &mt('default'); - if ($env{'form.custom'.$tool} == 1) { - $changed->{$tool} = &tool_admin($tool,$env{'form.'.$context.'_'.$tool}, - $changeHash,$context); + if (($env{'form.custom'.$tool} == 1) || + (($context eq 'authordefaults') && ($tool eq 'managers') && ($newval ne ''))) { + $changed->{$tool} = &tool_admin($tool,$newval,$changeHash, + $context); if ($changed->{$tool}) { $newaccess->{$tool} = &mt('custom'); - if ($env{'form.'.$context.'_'.$tool}) { - $newaccesstext->{$tool} = &mt("availability set to 'on'"); + if (($context eq 'requestcourses') || ($context eq 'requestauthor')) { + if ($newval =~ /^autolimit/) { + if ($limit) { + $newaccesstext->{$tool} = &mt('available with automatic approval, up to limit of [quant,_1,request] per user',$limit); + } else { + $newaccesstext->{$tool} = &mt('available with automatic approval (unlimited)'); + } + } elsif ($newval) { + $newaccesstext->{$tool} = $reqdisplay{$newval}; + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } elsif ($context eq 'authordefaults') { + if ($tool eq 'managers') { + if ($newval eq '') { + $newaccesstext->{$tool} = &mt('Only author may manage co-author roles'); + } else { + my $managers = $newval; + $managers =~ s/,/, /g; + $newaccesstext->{$tool} = $managers; + } + } elsif ($tool eq 'editors') { + $newaccesstext->{$tool} = &mt('can use: [_1]', + join(', ', map { $tooldesc{$_} } split(/,/,$newval))); + } elsif ($tool eq 'webdav') { + if ($newval) { + $newaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } + } } else { - $newaccesstext->{$tool} = &mt("availability set to 'off'"); + if ($newval) { + $newaccesstext->{$tool} = &mt("availability set to 'on'"); + } else { + $newaccesstext->{$tool} = &mt("availability set to 'off'"); + } } } else { $newaccess->{$tool} = $oldaccess->{$tool}; @@ -2623,12 +4550,18 @@ sub tool_changes { } sub update_roles { - my ($r,$context) = @_; + my ($r,$context,$showcredits) = @_; my $now=time; my @rolechanges; - my %disallowed; + my (%disallowed,%got_role_approvals,%got_instdoms,%process_by,%instdoms, + %pending,%reject,%notifydc,%status,%unauthorized,%currqueued); + $got_role_approvals{$context} = ''; + $process_by{$context} = {}; + my @domroles = &Apache::lonuserutils::domain_roles(); + my @cstrroles = &Apache::lonuserutils::construction_space_roles(); + my @courseroles = &Apache::lonuserutils::roles_by_context('course',1); $r->print('

'.&mt('Modifying Roles').'

'); - foreach my $key (keys (%env)) { + foreach my $key (keys(%env)) { next if (! $env{$key}); next if ($key eq 'form.action'); # Revoke roles @@ -2640,14 +4573,20 @@ sub update_roles { &Apache::lonnet::revokerole($env{'form.ccdomain'}, $env{'form.ccuname'}, $scope,$role,'','',$context); - $r->print(&mt('Revoking [_1] in [_2]: [_3]', - $role,$scope,''.$result.'').'
'); + $r->print(&Apache::lonhtmlcommon::confirm_success( + &mt('Revoking [_1] in [_2]', + &Apache::lonnet::plaintext($role), + &Apache::loncommon::show_role_extent($scope,$context,$role)), + $result ne "ok").'
'); + if ($result ne "ok") { + $r->print(&mt('Error: [_1]',$result).'
'); + } if ($role eq 'st') { my $result = &Apache::lonuserutils::classlist_drop($scope, $env{'form.ccuname'},$env{'form.ccdomain'}, $now); - $r->print($result); + $r->print(&Apache::lonhtmlcommon::confirm_success($result)); } if (!grep(/^\Q$role\E$/,@rolechanges)) { push(@rolechanges,$role); @@ -2655,11 +4594,15 @@ sub update_roles { } if ($key=~m{^form\.rev\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}s) { # Revoke custom role - $r->print(&mt('Revoking custom role:'). - ' '.$4.' by '.$3.':'.$2.' in '.$1.': '. - &Apache::lonnet::revokecustomrole($env{'form.ccdomain'}, - $env{'form.ccuname'},$1,$2,$3,$4,'','',$context). - '
'); + my $result = &Apache::lonnet::revokecustomrole( + $env{'form.ccdomain'},$env{'form.ccuname'},$1,$2,$3,$4,'','',$context); + $r->print(&Apache::lonhtmlcommon::confirm_success( + &mt('Revoking custom role [_1] by [_2] in [_3]', + $4,$3.':'.$2,&Apache::loncommon::show_role_extent($1,$context,'cr')), + $result ne 'ok').'
'); + if ($result ne "ok") { + $r->print(&mt('Error: [_1]',$result).'
'); + } if (!grep(/^cr$/,@rolechanges)) { push(@rolechanges,'cr'); } @@ -2673,14 +4616,21 @@ sub update_roles { $env{'form.ccuname'}, $scope,$role,$now,0,1,'', $context); - $r->print(&mt('Deleting [_1] in [_2]: [_3]',$role,$scope, - ''.$result.'').'
'); + $r->print(&Apache::lonhtmlcommon::confirm_success( + &mt('Deleting [_1] in [_2]', + &Apache::lonnet::plaintext($role), + &Apache::loncommon::show_role_extent($scope,$context,$role)), + $result ne 'ok').'
'); + if ($result ne "ok") { + $r->print(&mt('Error: [_1]',$result).'
'); + } + if ($role eq 'st') { my $result = &Apache::lonuserutils::classlist_drop($scope, $env{'form.ccuname'},$env{'form.ccdomain'}, $now); - $r->print($result); + $r->print(&Apache::lonhtmlcommon::confirm_success($result)); } if (!grep(/^\Q$role\E$/,@rolechanges)) { push(@rolechanges,$role); @@ -2689,11 +4639,17 @@ sub update_roles { if ($key=~m{^form\.del\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}) { my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4); # Delete custom role - $r->print(&mt('Deleting custom role [_1] by [_2] in [_3]', - $rolename,$rnam.':'.$rdom,$url).': '. - &Apache::lonnet::assigncustomrole($env{'form.ccdomain'}, - $env{'form.ccuname'},$url,$rdom,$rnam,$rolename,$now, - 0,1,$context).'
'); + my $result = + &Apache::lonnet::assigncustomrole($env{'form.ccdomain'}, + $env{'form.ccuname'},$url,$rdom,$rnam,$rolename,$now, + 0,1,$context); + $r->print(&Apache::lonhtmlcommon::confirm_success(&mt('Deleting custom role [_1] by [_2] in [_3]', + $rolename,$rnam.':'.$rdom,&Apache::loncommon::show_role_extent($1,$context,'cr')), + $result ne "ok").'
'); + if ($result ne "ok") { + $r->print(&mt('Error: [_1]',$result).'
'); + } + if (!grep(/^cr$/,@rolechanges)) { push(@rolechanges,'cr'); } @@ -2705,31 +4661,66 @@ sub update_roles { if ($key=~/^form\.ren\:([^\_]+)\_([^\_\.]+)$/) { my $url = $1; my $role = $2; + my $id = $url.'_'.$role; my $logmsg; my $output; if ($role eq 'st') { if ($url =~ m-^/($match_domain)/($match_courseid)/?(\w*)$-) { - my $result = &Apache::loncommon::commit_studentrole(\$logmsg,$udom,$uname,$url,$role,$now,0,$1,$2,$3); + my ($cdom,$cnum,$csec) = ($1,$2,$3); + my $credits; + if ($showcredits) { + my $defaultcredits = + &Apache::lonuserutils::get_defaultcredits($cdom,$cnum); + $credits = &get_user_credits($defaultcredits,$cdom,$cnum); + } + unless ($udom eq $cdom) { + next if (&Apache::lonuserutils::restricted_dom($context,$id,$udom, + $uname,$role,$now,0,$cdom,$cnum,$csec,$credits, + \%process_by,\%instdoms,\%got_role_approvals, + \%got_instdoms,\%reject,\%pending,\%notifydc, + \%status,\%unauthorized,\%currqueued)); + } + my $result = &Apache::loncommon::commit_studentrole(\$logmsg,$udom,$uname,$url,$role,$now,0,$cdom,$cnum,$csec,$context,$credits); if (($result =~ /^error/) || ($result eq 'not_in_class') || ($result eq 'unknown_course') || ($result eq 'refused')) { if ($result eq 'refused' && $logmsg) { $output = $logmsg; } else { - $output = "Error: $result\n"; + $output = &mt('Error: [_1]',$result)."\n"; } } else { - $output = &mt('Assigning').' '.$role.' in '.$url. - &mt('starting').' '.localtime($now). - ':
'.$logmsg.'
'. - &mt('Add to classlist').': ok
'; + $output = &Apache::lonhtmlcommon::confirm_success(&mt('Assigning [_1] in [_2] starting [_3]', + &Apache::lonnet::plaintext($role), + &Apache::loncommon::show_role_extent($url,$context,'st'), + &Apache::lonlocal::locallocaltime($now))).'
'.$logmsg.'
'; } } } else { + my ($cdom,$cnum,$csec); + if (grep(/^\Q$role\E$/,@cstrroles)) { + ($cdom,$cnum) = ($url =~ m{^/($match_domain)/($match_username)$}); + } elsif (grep(/^\Q$role\E$/,@domroles)) { + ($cdom) = ($url =~ m{^/($match_domain)/$}); + } elsif ($url =~ m-^/($match_domain)/($match_courseid)/?(\w*)$-) { + ($cdom,$cnum,$csec) = ($1,$2,$3); + } + if ($cdom ne '') { + unless ($udom eq $cdom) { + next if (&Apache::lonuserutils::restricted_dom($context,$id,$udom, + $uname,$role,$now,0,$cdom,$cnum,$csec,'',\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued)); + } + } my $result=&Apache::lonnet::assignrole($env{'form.ccdomain'}, $env{'form.ccuname'},$url,$role,0,$now,'','', $context); - $output = &mt('Re-enabling [_1] in [_2]: [_3]', - $role,$url,''.$result.'').'
'; - } + $output = &Apache::lonhtmlcommon::confirm_success(&mt('Re-enabling [_1] in [_2]', + &Apache::lonnet::plaintext($role), + &Apache::loncommon::show_role_extent($url,$context,$role)),$result ne "ok").'
'; + if ($result ne "ok") { + $output .= &mt('Error: [_1]',$result).'
'; + } + } $r->print($output); if (!grep(/^\Q$role\E$/,@rolechanges)) { push(@rolechanges,$role); @@ -2738,11 +4729,27 @@ sub update_roles { # Re-enable custom role if ($key=~m{^form\.ren\:([^_]+)_cr\.cr/($match_domain)/($match_username)/(\w+)$}) { my ($url,$rdom,$rnam,$rolename) = ($1,$2,$3,$4); + my $id = $url.'_cr'."/$rdom/$rnam/$rolename"; + my $role = "cr/$rdom/$rnam/$rolename"; + if ($url =~ m-^/($match_domain)/($match_courseid)/?(\w*)$-) { + my ($cdom,$cnum,$csec) = ($1,$2,$3); + unless ($udom eq $cdom) { + next if (&Apache::lonuserutils::restricted_dom($context,$id,$udom, + $uname,$role,$now,0,$cdom,$cnum,$csec,'',\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued)); + } + } my $result = &Apache::lonnet::assigncustomrole( $env{'form.ccdomain'}, $env{'form.ccuname'}, $url,$rdom,$rnam,$rolename,0,$now,undef,$context); - $r->print(&mt('Re-enabling custom role [_1] by [_2] in [_3]: [_4]', - $rolename,$rnam.':'.$rdom,$url,''.$result.'').'
'); + $r->print(&Apache::lonhtmlcommon::confirm_success( + &mt('Re-enabling custom role [_1] by [_2] in [_3]', + $rolename,$rnam.':'.$rdom,&Apache::loncommon::show_role_extent($1,$context,'cr')), + $result ne "ok").'
'); + if ($result ne "ok") { + $r->print(&mt('Error: [_1]',$result).'
'); + } if (!grep(/^cr$/,@rolechanges)) { push(@rolechanges,'cr'); } @@ -2754,6 +4761,8 @@ sub update_roles { # Activate a custom role my ($one,$two,$three,$four,$five)=($1,$2,$3,$4,$5); my $url='/'.$one.'/'.$two; + my $id = $url.'_cr/'."$three/$four/$five"; + my $role = "cr/$three/$four/$five"; my $full=$one.'_'.$two.'_cr_cr_'.$three.'_'.$four.'_'.$five; my $start = ( $env{'form.start_'.$full} ? @@ -2762,24 +4771,41 @@ sub update_roles { my $end = ( $env{'form.end_'.$full} ? $env{'form.end_'.$full} : 0 ); - + # split multiple sections my %sections = (); - my $num_sections = &build_roles($env{'form.sec_'.$full},\%sections,$5); + my $num_sections = &build_roles($env{'form.sec_'.$full},\%sections,$five); if ($num_sections == 0) { + unless ($udom eq $one) { + next if (&Apache::lonuserutils::restricted_dom($context,$id,$udom, + $uname,$role,$start,$end,$one,$two,'','',\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued)); + } $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$url,$three,$four,$five,$start,$end,$context)); } else { my %curr_groups = &Apache::longroup::coursegroups($one,$two); - foreach my $sec (sort {$a cmp $b} keys %sections) { + my ($restricted,$numchanges); + foreach my $sec (sort {$a cmp $b} keys(%sections)) { if (($sec eq 'none') || ($sec eq 'all') || exists($curr_groups{$sec})) { $disallowed{$sec} = $url; next; } my $securl = $url.'/'.$sec; + my $secid = $securl.'_cr'."/$three/$four/$five"; + undef($restricted); + unless ($udom eq $one) { + next if (&Apache::lonuserutils::restricted_dom($context,$secid,$udom, + $uname,$role,$start,$end,$one,$two,$sec,'',\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued)); + } + $numchanges ++; $r->print(&Apache::loncommon::commit_customrole($udom,$uname,$securl,$three,$four,$five,$start,$end,$context)); } + next unless ($numchanges); } if (!grep(/^cr$/,@rolechanges)) { push(@rolechanges,'cr'); @@ -2788,24 +4814,44 @@ sub update_roles { # Activate roles for sections with 3 id numbers # set start, end times, and the url for the class my ($one,$two,$three)=($1,$2,$3); - my $start = ( $env{'form.start_'.$one.'_'.$two.'_'.$three} ? - $env{'form.start_'.$one.'_'.$two.'_'.$three} : + my $start = ( $env{'form.start_'.$one.'_'.$two.'_'.$three} ? + $env{'form.start_'.$one.'_'.$two.'_'.$three} : $now ); - my $end = ( $env{'form.end_'.$one.'_'.$two.'_'.$three} ? + my $end = ( $env{'form.end_'.$one.'_'.$two.'_'.$three} ? $env{'form.end_'.$one.'_'.$two.'_'.$three} : 0 ); my $url='/'.$one.'/'.$two; - my $type = 'three'; + my $id = $url.'_'.$three; # split multiple sections my %sections = (); my $num_sections = &build_roles($env{'form.sec_'.$one.'_'.$two.'_'.$three},\%sections,$three); + my ($credits,$numchanges); + if ($three eq 'st') { + if ($showcredits) { + my $defaultcredits = + &Apache::lonuserutils::get_defaultcredits($one,$two); + $credits = $env{'form.credits_'.$one.'_'.$two.'_'.$three}; + $credits =~ s/[^\d\.]//g; + if ($credits eq $defaultcredits) { + undef($credits); + } + } + } if ($num_sections == 0) { - $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'',$context)); + unless ($udom eq $one) { + next if (&Apache::lonuserutils::restricted_dom($context,$id,$udom, + $uname,$three,$start,$end,$one,$two,'',$credits,\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued)); + } + $numchanges ++; + $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'',$context,$credits)); } else { my %curr_groups = &Apache::longroup::coursegroups($one,$two); my $emptysec = 0; - foreach my $sec (sort {$a cmp $b} keys %sections) { + my $restricted; + foreach my $sec (sort {$a cmp $b} keys(%sections)) { $sec =~ s/\W//g; if ($sec ne '') { if (($sec eq 'none') || ($sec eq 'all') || @@ -2814,14 +4860,34 @@ sub update_roles { next; } my $securl = $url.'/'.$sec; - $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$three,$start,$end,$one,$two,$sec,$context)); + my $secid = $securl.'_'.$three; + unless ($udom eq $one) { + undef($restricted); + $restricted = &Apache::lonuserutils::restricted_dom($context,$secid,$udom, + $uname,$three,$start,$end,$one,$two,$sec,$credits,\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued); + next if ($restricted); + } + $numchanges ++; + $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$three,$start,$end,$one,$two,$sec,$context,$credits)); } else { $emptysec = 1; } } if ($emptysec) { - $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'',$context)); + unless ($udom eq $one) { + undef($restricted); + $restricted = &Apache::lonuserutils::restricted_dom($context,$id,$udom, + $uname,$three,$start,$end,$one,$two,'',$credits,\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued); + next if ($restricted); + } + $numchanges ++; + $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$three,$start,$end,$one,$two,'',$context,$credits)); } + next unless ($numchanges); } if (!grep(/^\Q$three\E$/,@rolechanges)) { push(@rolechanges,$three); @@ -2829,33 +4895,64 @@ sub update_roles { } elsif ($key=~/^form\.act\_([^\_]+)\_([^\_]+)$/) { # Activate roles for sections with two id numbers # set start, end times, and the url for the class - my $start = ( $env{'form.start_'.$1.'_'.$2} ? - $env{'form.start_'.$1.'_'.$2} : + my $start = ( $env{'form.start_'.$1.'_'.$2} ? + $env{'form.start_'.$1.'_'.$2} : $now ); - my $end = ( $env{'form.end_'.$1.'_'.$2} ? + my $end = ( $env{'form.end_'.$1.'_'.$2} ? $env{'form.end_'.$1.'_'.$2} : 0 ); my $one = $1; my $two = $2; my $url='/'.$one.'/'; + my $id = $url.'_'.$two; + my ($cdom,$cnum) = split(/\//,$one); # split multiple sections my %sections = (); + my ($restricted,$numchanges); my $num_sections = &build_roles($env{'form.sec_'.$one.'_'.$two},\%sections,$two); if ($num_sections == 0) { + unless ($udom eq $one) { + $restricted = &Apache::lonuserutils::restricted_dom($context,$id,$udom, + $uname,$two,$start,$end,$cdom,$cnum,'','',\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued); + next if ($restricted); + } + $numchanges ++; $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$two,$start,$end,$one,undef,'',$context)); } else { my $emptysec = 0; - foreach my $sec (sort {$a cmp $b} keys %sections) { + foreach my $sec (sort {$a cmp $b} keys(%sections)) { if ($sec ne '') { my $securl = $url.'/'.$sec; + my $secid = $securl.'_'.$two; + unless ($udom eq $one) { + undef($restricted); + $restricted = &Apache::lonuserutils::restricted_dom($context,$secid,$udom, + $uname,$two,$start,$end,$cdom,$cnum,$sec,'',\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued); + next if ($restricted); + } + $numchanges ++; $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$securl,$two,$start,$end,$one,undef,$sec,$context)); } else { $emptysec = 1; } } if ($emptysec) { + unless ($udom eq $one) { + undef($restricted); + $restricted = &Apache::lonuserutils::restricted_dom($context,$id,$udom, + $uname,$two,$start,$end,$cdom,$cnum,'','',\%process_by, + \%instdoms,\%got_role_approvals,\%got_instdoms,\%reject, + \%pending,\%notifydc,\%status,\%unauthorized,\%currqueued); + next if ($restricted); + } + $numchanges ++; $r->print(&Apache::loncommon::commit_standardrole($udom,$uname,$url,$two,$start,$end,$one,undef,'',$context)); } + next unless ($numchanges); } if (!grep(/^\Q$two\E$/,@rolechanges)) { push(@rolechanges,$two); @@ -2879,33 +4976,104 @@ sub update_roles { } } } # End of foreach (keys(%env)) + if ((keys(%reject)) || (keys(%unauthorized))) { + $r->print(&Apache::lonuserutils::print_roles_rejected($context,\%reject,\%unauthorized)); + } + if ((keys(%pending)) || (keys(%currqueued))) { + $r->print(&Apache::lonuserutils::print_roles_queued($context,\%pending,\%notifydc,\%currqueued)); + } # Flush the course logs so reverse user roles immediately updated - &Apache::lonnet::flushcourselogs(); + $r->register_cleanup(\&Apache::lonnet::flushcourselogs); if (@rolechanges == 0) { - $r->print(&mt('No roles to modify')); + $r->print('

'.&mt('No roles to modify').'

'); } return @rolechanges; } +sub get_user_credits { + my ($uname,$udom,$defaultcredits,$cdom,$cnum) = @_; + if ($cdom eq '' || $cnum eq '') { + return unless ($env{'request.course.id'}); + $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + } + my $credits; + my %currhash = + &Apache::lonnet::get('classlist',[$uname.':'.$udom],$cdom,$cnum); + if (keys(%currhash) > 0) { + my @items = split(/:/,$currhash{$uname.':'.$udom}); + my $crdidx = &Apache::loncoursedata::CL_CREDITS() - 3; + $credits = $items[$crdidx]; + $credits =~ s/[^\d\.]//g; + } + if ($credits eq $defaultcredits) { + undef($credits); + } + return $credits; +} + sub enroll_single_student { - my ($r,$uhome,$amode,$genpwd,$now,$newuser,$context) = @_; - $r->print('

'.&mt('Enrolling Student').'

'); + my ($r,$uhome,$amode,$genpwd,$now,$newuser,$context,$crstype, + $showcredits,$defaultcredits) = @_; + $r->print('

'); + if ($crstype eq 'Community') { + $r->print(&mt('Enrolling Member')); + } else { + $r->print(&mt('Enrolling Student')); + } + $r->print('

'); # Remove non alphanumeric values from section $env{'form.sections'}=~s/\W//g; + my $credits; + if (($showcredits) && ($env{'form.credits'} ne '')) { + $credits = $env{'form.credits'}; + $credits =~ s/[^\d\.]//g; + if ($credits ne '') { + if ($credits eq $defaultcredits) { + undef($credits); + } + } + } + my ($startdate,$enddate) = &Apache::lonuserutils::get_dates_from_form(); + my (%got_role_approvals,%got_instdoms,%process_by,%instdoms,%pending,%reject,%notifydc, + %status,%unauthorized,%currqueued); + unless ($env{'form.ccdomain'} eq $env{'course.'.$env{'request.course.id'}.'.domain'}) { + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $csec = $env{'form.sections'}; + my $id = "/$cdom/$cnum"; + if ($csec ne '') { + $id .= "/$csec"; + } + $id .= '_st'; + if (&Apache::lonuserutils::restricted_dom($context,$id,$env{'form.ccdomain'},$env{'form.ccuname'}, + 'st',$startdate,$enddate,$cdom,$cnum,$csec,$credits, + \%process_by,\%instdoms,\%got_role_approvals,\%got_instdoms, + \%reject,\%pending,\%notifydc,\%status,\%unauthorized,\%currqueued)) { + if ((keys(%reject)) || (keys(%unauthorized))) { + $r->print(&Apache::lonuserutils::print_roles_rejected($context,\%reject,\%unauthorized)); + } + if ((keys(%pending)) || (keys(%currqueued))) { + $r->print(&Apache::lonuserutils::print_roles_queued($context,\%pending,\%notifydc,\%currqueued)); + } + return; + } + } + # Clean out any old student roles the user has in this class. &Apache::lonuserutils::modifystudent($env{'form.ccdomain'}, $env{'form.ccuname'},$env{'request.course.id'},undef,$uhome); - my ($startdate,$enddate) = &Apache::lonuserutils::get_dates_from_form(); my $enroll_result = &Apache::lonnet::modify_student_enrollment($env{'form.ccdomain'}, $env{'form.ccuname'},$env{'form.cid'},$env{'form.cfirstname'}, $env{'form.cmiddlename'},$env{'form.clastname'}, $env{'form.generation'},$env{'form.sections'},$enddate, - $startdate,'manual',undef,$env{'request.course.id'},'',$context); + $startdate,'manual',undef,$env{'request.course.id'},'',$context, + $credits); if ($enroll_result =~ /^ok/) { - $r->print(&mt('[_1] enrolled',$env{'form.ccuname'}.':'.$env{'form.ccdomain'})); + $r->print(&mt('[_1] enrolled',''.$env{'form.ccuname'}.':'.$env{'form.ccdomain'}.'')); if ($env{'form.sections'} ne '') { $r->print(' '.&mt('in section [_1]',$env{'form.sections'})); } @@ -2922,7 +5090,13 @@ sub enroll_single_student { } $r->print('.
'.$showstart.'; '.$showend); if ($startdate <= $now && !$newuser) { - $r->print("

".&mt('If the student is currently logged-in to LON-CAPA, the new role will be available when the student next logs in.')."

"); + $r->print('

'); + if ($crstype eq 'Community') { + $r->print(&mt('If the member is currently logged-in to LON-CAPA, the new role can be displayed by using the "Check for changes" link on the Roles/Courses page.')); + } else { + $r->print(&mt('If the student is currently logged-in to LON-CAPA, the new role can be displayed by using the "Check for changes" link on the Roles/Courses page.')); + } + $r->print('

'); } } else { $r->print(&mt('unable to enroll').": ".$enroll_result); @@ -2934,14 +5108,14 @@ sub get_defaultquota_text { my ($settingstatus) = @_; my $defquotatext; if ($settingstatus eq '') { - $defquotatext = &mt('(default)'); + $defquotatext = &mt('default'); } else { my ($usertypes,$order) = &Apache::lonnet::retrieve_inst_usertypes($env{'form.ccdomain'}); if ($usertypes->{$settingstatus} eq '') { - $defquotatext = &mt('(default)'); + $defquotatext = &mt('default'); } else { - $defquotatext = &mt('(default for [_1])',$usertypes->{$settingstatus}); + $defquotatext = &mt('default for [_1]',$usertypes->{$settingstatus}); } } return $defquotatext; @@ -2950,7 +5124,7 @@ sub get_defaultquota_text { sub update_result_form { my ($uhome) = @_; my $outcome = - ''."\n"; + ''."\n"; foreach my $item ('srchby','srchin','srchtype','srchterm','srchdomain','ccuname','ccdomain') { $outcome .= ''."\n"; } @@ -2966,20 +5140,20 @@ sub update_result_form { $outcome .= ''."\n"; } $outcome .= ''."\n". - ''."\n". - ''."\n". + ''."\n". + ''."\n". ''; return $outcome; } sub quota_admin { - my ($setquota,$changeHash) = @_; + my ($setquota,$changeHash,$name) = @_; my $quotachanged; if (&Apache::lonnet::allowed('mpq',$env{'form.ccdomain'})) { # Current user has quota modification privileges if (ref($changeHash) eq 'HASH') { $quotachanged = 1; - $changeHash->{'portfolioquota'} = $setquota; + $changeHash->{$name.'quota'} = $setquota; } } return $quotachanged; @@ -2992,6 +5166,18 @@ sub tool_admin { if (&Apache::lonnet::allowed('ccc',$env{'form.ccdomain'})) { $canchange = 1; } + } elsif ($context eq 'reqcrsotherdom') { + if (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) { + $canchange = 1; + } + } elsif ($context eq 'requestauthor') { + if (&Apache::lonnet::allowed('cau',$env{'request.role.domain'})) { + $canchange = 1; + } + } elsif ($context eq 'authordefaults') { + if (&Apache::lonnet::allowed('cau',$env{'request.role.domain'})) { + $canchange = 1; + } } elsif (&Apache::lonnet::allowed('mut',$env{'form.ccdomain'})) { # Current user has quota modification privileges $canchange = 1; @@ -3000,7 +5186,15 @@ sub tool_admin { if ($canchange) { if (ref($changeHash) eq 'HASH') { $toolchanged = 1; - $changeHash->{$context.'.'.$tool} = $settool; + if ($tool eq 'requestauthor') { + $changeHash->{$context} = $settool; + } elsif (($tool eq 'managers') || ($tool eq 'editors')) { + $changeHash->{'author'.$tool} = $settool; + } elsif ($tool eq 'webdav') { + $changeHash->{'tools.'.$tool} = $settool; + } else { + $changeHash->{$context.'.'.$tool} = $settool; + } } } return $toolchanged; @@ -3042,240 +5236,148 @@ sub build_roles { # ========================================================== Custom Role Editor sub custom_role_editor { - my ($r) = @_; - my $rolename=$env{'form.rolename'}; + my ($r,$context,$brcrum,$prefix,$permission) = @_; + my $action = $env{'form.customroleaction'}; + my ($rolename,$helpitem); + if ($action eq 'new') { + $rolename=$env{'form.newrolename'}; + } else { + $rolename=$env{'form.rolename'}; + } - if ($rolename eq 'make new role') { - $rolename=$env{'form.newrolename'}; + my ($crstype,$context); + if ($env{'request.course.id'}) { + $crstype = &Apache::loncommon::course_type(); + $context = 'course'; + $helpitem = 'Course_Editing_Custom_Roles'; + } else { + $context = 'domain'; + $crstype = 'course'; + $helpitem = 'Domain_Editing_Custom_Roles'; } $rolename=~s/[^A-Za-z0-9]//gs; - if (!$rolename || $env{'form.phase'} eq 'pickrole') { - &print_username_entry_form($r); + &print_username_entry_form($r,$context,undef,undef,undef,$crstype,$brcrum, + $permission); return; } -# ------------------------------------------------------- What can be assigned? - my %full=(); - my %courselevel=(); - my %courselevelcurrent=(); - my $syspriv=''; - my $dompriv=''; - my $coursepriv=''; - my $body_top; - my ($disp_dummy,$disp_roles) = &Apache::lonnet::get('roles',["st"]); + + my $formname = 'form1'; + my %privs=(); + my $body_top = '

'; +# ------------------------------------------------------- Does this role exist? my ($rdummy,$roledef)= &Apache::lonnet::get('roles',["rolesdef_$rolename"]); -# ------------------------------------------------------- Does this role exist? - $body_top .= '

'; if (($rdummy ne 'con_lost') && ($roledef ne '')) { - $body_top .= &mt('Existing Role').' "'; + $body_top .= &mt('Existing Role').' "'; # ------------------------------------------------- Get current role privileges - ($syspriv,$dompriv,$coursepriv)=split(/\_/,$roledef); + ($privs{'system'},$privs{'domain'},$privs{'course'})=split(/\_/,$roledef); + if ($privs{'system'} =~ /bre\&S/) { + if ($context eq 'domain') { + $crstype = 'Course'; + } elsif ($crstype eq 'Community') { + $privs{'system'} =~ s/bre\&S//; + } + } elsif ($context eq 'domain') { + $crstype = 'Course'; + } } else { - $body_top .= &mt('New Role').' "'; - $roledef=''; + $body_top .= &mt('New Role').' "'; + $roledef=''; } $body_top .= $rolename.'"

'; - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { - my ($priv,$restrict)=split(/\&/,$item); - if (!$restrict) { $restrict='F'; } - $courselevel{$priv}=$restrict; - if ($coursepriv=~/\:$priv/) { - $courselevelcurrent{$priv}=1; - } - $full{$priv}=1; - } - my %domainlevel=(); - my %domainlevelcurrent=(); - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) { - my ($priv,$restrict)=split(/\&/,$item); - if (!$restrict) { $restrict='F'; } - $domainlevel{$priv}=$restrict; - if ($dompriv=~/\:$priv/) { - $domainlevelcurrent{$priv}=1; - } - $full{$priv}=1; - } - my %systemlevel=(); - my %systemlevelcurrent=(); - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) { - my ($priv,$restrict)=split(/\&/,$item); - if (!$restrict) { $restrict='F'; } - $systemlevel{$priv}=$restrict; - if ($syspriv=~/\:$priv/) { - $systemlevelcurrent{$priv}=1; - } - $full{$priv}=1; - } - my ($jsback,$elements) = &crumb_utilities(); - my $button_code = "\n"; - my $head_script = "\n"; - $head_script .= ''."\n"; - $r->print(&Apache::loncommon::start_page('Custom Role Editor',$head_script)); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage(document.form1,'pickrole','')", - text=>"Pick custom role", - faq=>282,bug=>'Instructor Interface',}, - {href=>"javascript:backPage(document.form1,'','')", - text=>"Edit custom role", - faq=>282,bug=>'Instructor Interface',}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', - 'Course_Editing_Custom_Roles')); - $r->print($body_top); - my %lt=&Apache::lonlocal::texthash( - 'prv' => "Privilege", - 'crl' => "Course Level", - 'dml' => "Domain Level", - 'ssl' => "System Level"); - - $r->print('
' - .'
' - .''.&mt('Select a Template').'' - .$button_code - .'
' - .'
' - ); +# ------------------------------------------------------- What can be assigned? + my %full=(); + my %levels=( + course => {}, + domain => {}, + system => {}, + ); + my %levelscurrent=( + course => {}, + domain => {}, + system => {}, + ); + &Apache::lonuserutils::custom_role_privs(\%privs,\%full,\%levels,\%levelscurrent); + my ($jsback,$elements) = &crumb_utilities(); + my @templateroles = &Apache::lonuserutils::custom_template_roles($context,$crstype); + my $head_script = + &Apache::lonuserutils::custom_roledefs_js($context,$crstype,$formname, + \%full,\@templateroles,$jsback); + push (@{$brcrum}, + {href => "javascript:backPage(document.$formname,'pickrole','')", + text => "Pick custom role", + faq => 282,bug=>'Instructor Interface',}, + {href => "javascript:backPage(document.$formname,'','')", + text => "Edit custom role", + faq => 282, + bug => 'Instructor Interface', + help => $helpitem} + ); + my $args = { bread_crumbs => $brcrum, + bread_crumbs_component => 'User Management'}; + $r->print(&Apache::loncommon::start_page('Custom Role Editor', + $head_script,$args). + $body_top); + $r->print(''."\n". + &Apache::lonuserutils::custom_role_header($context,$crstype, + \@templateroles,$prefix)); $r->print(< ENDCCF - $r->print(&Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_header_row(). -''. - &Apache::loncommon::end_data_table_header_row()); - foreach my $priv (sort keys %full) { - my $privtext = &Apache::lonnet::plaintext($priv); - $r->print(&Apache::loncommon::start_data_table_row(). - ''. - &Apache::loncommon::end_data_table_row()); - } + $r->print(&Apache::lonuserutils::custom_role_table($crstype,\%full,\%levels, + \%levelscurrent,$prefix)); $r->print(&Apache::loncommon::end_data_table(). ''. ''."\n".''."\n". + '" />'."\n".''."\n". ''."\n". - ''. - &Apache::loncommon::end_page()); -} -# -------------------------------------------------------- -sub make_script_template { - my ($role) = @_; - my %full_c=(); - my %full_d=(); - my %full_s=(); - my $return_script; - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { - my ($priv,$restrict)=split(/\&/,$item); - $full_c{$priv}=1; - } - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) { - my ($priv,$restrict)=split(/\&/,$item); - $full_d{$priv}=1; - } - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) { - my ($priv,$restrict)=split(/\&/,$item); - $full_s{$priv}=1; - } - $return_script .= 'function set_'.$role.'() {'."\n"; - my @temp = split(/:/,$Apache::lonnet::pr{$role.':c'}); - my %role_c; - foreach my $priv (@temp) { - my ($priv_item, $dummy) = split(/\&/,$priv); - $role_c{$priv_item} = 1; - } - my %role_d; - @temp = split(/:/,$Apache::lonnet::pr{$role.':d'}); - foreach my $priv(@temp) { - my ($priv_item, $dummy) = split(/\&/,$priv); - $role_d{$priv_item} = 1; - } - my %role_s; - @temp = split(/:/,$Apache::lonnet::pr{$role.':s'}); - foreach my $priv(@temp) { - my ($priv_item, $dummy) = split(/\&/,$priv); - $role_s{$priv_item} = 1; - } - foreach my $priv_item (keys(%full_c)) { - my ($priv, $dummy) = split(/\&/,$priv_item); - if ((exists($role_c{$priv})) || (exists($role_d{$priv})) || - (exists($role_s{$priv}))) { - $return_script .= "document.form1.$priv"."_c.checked = true;\n"; - } else { - $return_script .= "document.form1.$priv"."_c.checked = false;\n"; - } - } - foreach my $priv_item (keys(%full_d)) { - my ($priv, $dummy) = split(/\&/,$priv_item); - if ((exists($role_d{$priv})) || (exists($role_s{$priv}))) { - $return_script .= "document.form1.$priv"."_d.checked = true;\n"; - } else { - $return_script .= "document.form1.$priv"."_d.checked = false;\n"; - } - } - foreach my $priv_item (keys(%full_s)) { - my ($priv, $dummy) = split(/\&/,$priv_item); - if (exists($role_s{$priv})) { - $return_script .= "document.form1.$priv"."_s.checked = true;\n"; - } else { - $return_script .= "document.form1.$priv"."_s.checked = false;\n"; - } - } - $return_script .= '}'."\n"; - return ($return_script); -} -# ---------------------------------------------------------- -sub make_button_code { - my ($role) = @_; - my $label = &Apache::lonnet::plaintext($role); - my $button_code = ''; - return ($button_code); + ''); } + # ---------------------------------------------------------- Call to definerole sub set_custom_role { - my ($r,$context) = @_; + my ($r,$context,$brcrum,$prefix,$permission) = @_; my $rolename=$env{'form.rolename'}; $rolename=~s/[^A-Za-z0-9]//gs; if (!$rolename) { - &custom_role_editor($r); + &custom_role_editor($r,$context,$brcrum,$prefix,$permission); return; } my ($jsback,$elements) = &crumb_utilities(); - my $jscript = ''; - - $r->print(&Apache::loncommon::start_page('Save Custom Role'),$jscript); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage(document.customresult,'pickrole','')", - text=>"Pick custom role", - faq=>282,bug=>'Instructor Interface',}, - {href=>"javascript:backPage(document.customresult,'selected_custom_edit','')", - text=>"Edit custom role", - faq=>282,bug=>'Instructor Interface',}, - {href=>"javascript:backPage(document.customresult,'set_custom_roles','')", - text=>"Result", - faq=>282,bug=>'Instructor Interface',}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', - 'Course_Editing_Custom_Roles')); + my $jscript = ''."\n"; + my $helpitem = 'Course_Editing_Custom_Roles'; + if ($context eq 'domain') { + $helpitem = 'Domain_Editing_Custom_Roles'; + } + push(@{$brcrum}, + {href => "javascript:backPage(document.customresult,'pickrole','')", + text => "Pick custom role", + faq => 282, + bug => 'Instructor Interface',}, + {href => "javascript:backPage(document.customresult,'selected_custom_edit','')", + text => "Edit custom role", + faq => 282, + bug => 'Instructor Interface',}, + {href => "javascript:backPage(document.customresult,'set_custom_roles','')", + text => "Result", + faq => 282, + bug => 'Instructor Interface', + help => $helpitem,} + ); + my $args = { bread_crumbs => $brcrum, + bread_crumbs_component => 'User Management'}; + $r->print(&Apache::loncommon::start_page('Save Custom Role',$jscript,$args)); + my $newrole; my ($rdummy,$roledef)= &Apache::lonnet::get('roles',["rolesdef_$rolename"]); @@ -3286,52 +5388,233 @@ sub set_custom_role { } else { $r->print(&mt('New Role').' "'); $roledef=''; + $newrole = 1; } $r->print($rolename.'"'); -# ------------------------------------------------------- What can be assigned? - my $sysrole=''; - my $domrole=''; - my $courole=''; - - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { - my ($priv,$restrict)=split(/\&/,$item); - if (!$restrict) { $restrict=''; } - if ($env{'form.'.$priv.'_c'}) { - $courole.=':'.$item; - } - } - - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:d'})) { - my ($priv,$restrict)=split(/\&/,$item); - if (!$restrict) { $restrict=''; } - if ($env{'form.'.$priv.'_d'}) { - $domrole.=':'.$item; - } - } +# ------------------------------------------------- Assign role and show result - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:s'})) { - my ($priv,$restrict)=split(/\&/,$item); - if (!$restrict) { $restrict=''; } - if ($env{'form.'.$priv.'_s'}) { - $sysrole.=':'.$item; - } - } - $r->print('
Defining Role: '. - &Apache::lonnet::definerole($rolename,$sysrole,$domrole,$courole)); + my $errmsg; + my %newprivs = &Apache::lonuserutils::custom_role_update($rolename,$prefix); + # Assign role and return result + my $result = &Apache::lonnet::definerole($rolename,$newprivs{'s'},$newprivs{'d'}, + $newprivs{'c'}); + if ($result ne 'ok') { + $errmsg = ': '.$result; + } + my $message = + &Apache::lonhtmlcommon::confirm_success( + &mt('Defining Role').$errmsg, ($result eq 'ok' ? 0 : 1)); if ($env{'request.course.id'}) { my $url='/'.$env{'request.course.id'}; $url=~s/\_/\//g; - $r->print('
'.&mt('Assigning Role to Self').': '. - &Apache::lonnet::assigncustomrole($env{'user.domain'}, - $env{'user.name'}, - $url, - $env{'user.domain'}, - $env{'user.name'}, - $rolename,undef,undef,undef,$context)); + $result = + &Apache::lonnet::assigncustomrole( + $env{'user.domain'},$env{'user.name'}, + $url, + $env{'user.domain'},$env{'user.name'}, + $rolename,undef,undef,undef,$context); + if ($result ne 'ok') { + $errmsg = ': '.$result; + } + $message .= + '
' + .&Apache::lonhtmlcommon::confirm_success( + &mt('Assigning Role to Self').$errmsg, ($result eq 'ok' ? 0 : 1)); + } + $r->print( + &Apache::loncommon::confirmwrapper($message) + .'
' + .&Apache::lonhtmlcommon::actionbox([ + '' + .&mt('Create or edit another custom role') + .'']) + .'' + .&Apache::lonhtmlcommon::echo_form_input([]) + .'' + ); +} + +sub show_role_requests { + my ($caller,$dom) = @_; + my $showrolereqs; + my %domconfig = &Apache::lonnet::get_dom('configuration',['privacy'],$dom); + if (ref($domconfig{'privacy'}) eq 'HASH') { + if (ref($domconfig{'privacy'}{'approval'}) eq 'HASH') { + my %approvalconf = %{$domconfig{'privacy'}{'approval'}}; + foreach my $key ('instdom','extdom') { + if (ref($approvalconf{$key}) eq 'HASH') { + if (keys(%{$approvalconf{$key}})) { + foreach my $context ('domain','author','course','community') { + if ($approvalconf{$key}{$context} eq $caller) { + $showrolereqs = 1; + last if ($showrolereqs); + } + } + } + } + last if ($showrolereqs); + } + } } - $r->print('

'.&mt('Create or edit another custom role').'

'); - $r->print(&Apache::lonhtmlcommon::echo_form_input([]).''); - $r->print(&Apache::loncommon::end_page()); + return $showrolereqs; +} + +sub display_coauthor_managers { + my ($permission) = @_; + my $output; + if ((ref($permission) eq 'HASH') && ($permission->{'author'})) { + $output = ''. + ''."\n". + '

'; + my (@possmanagers,@custommanagers); + my %userenv = + &Apache::lonnet::userenvironment($env{'user.domain'}, + $env{'user.name'}, + 'authormanagers'); + my %ca_roles = &Apache::lonnet::get_my_roles(undef,undef,undef, + ['active','future'],['ca']); + if (keys(%ca_roles)) { + foreach my $entry (sort(keys(%ca_roles))) { + if ($entry =~ /^($match_username\:$match_domain):ca$/) { + my $user = $1; + unless ($user eq $env{'user.name'}.':'.$env{'user.domain'}) { + push(@possmanagers,$user); + } + } + } + } + if ($userenv{'authormanagers'} eq '') { + $output .= &mt('Currently author manages co-author roles'); + } else { + if (keys(%ca_roles)) { + foreach my $user (split(/,/,$userenv{'authormanagers'})) { + if ($user =~ /^($match_username)\:($match_domain)$/) { + if (exists($ca_roles{$user.':ca'})) { + unless ($user eq $env{'user.name'}.':'.$env{'user.domain'}) { + push(@custommanagers,$user); + } + } + } + } + } + if (@custommanagers) { + $output .= &mt('Co-authors with active or future roles who currently manage co-author roles: [_1]', + '
'.join(', ',map { &Apache::loncommon::plainname(split(':',$_))." ($_)"; } @custommanagers)); + } else { + $output .= &mt('Currently author manages co-author roles'); + } + } + $output .= "

\n"; + if (@possmanagers) { + $output .= '

'.&mt('If checked, can manage').': '; + foreach my $user (@possmanagers) { + my $checked; + if (grep(/^\Q$user\E$/,@custommanagers)) { + $checked = ' checked="checked"'; + } + $output .= ' '."\n"; + } + $output .= '

'."\n". + '

'."\n"; + } else { + $output .= '

'.&mt('No co-author roles assignable as manager').'

'; + } + $output .= ''; + } else { + $output = ''. + &mt('You do not have permission to perform this action'). + ''; + } + return $output; +} + +sub update_coauthor_managers { + my ($permission) = @_; + my $output; + if ((ref($permission) eq 'HASH') && ($permission->{'author'})) { + my ($current,$newval,@possibles,@managers); + my %userenv = + &Apache::lonnet::userenvironment($env{'user.domain'}, + $env{'user.name'}, + 'authormanagers'); + $current = $userenv{'authormanagers'}; + @possibles = &Apache::loncommon::get_env_multiple('form.custommanagers'); + if (@possibles) { + my %ca_roles = &Apache::lonnet::get_my_roles(undef,undef,undef, + ['active','future'],['ca']); + if (keys(%ca_roles)) { + foreach my $user (@possibles) { + if ($user =~ /^($match_username):($match_domain)$/) { + if (exists($ca_roles{$user.':ca'})) { + unless ($user eq $env{'user.name'}.':'.$env{'user.domain'}) { + push(@managers,$user); + } + } + } + } + if (@managers) { + $newval = join(',',sort(@managers)); + } + } + } + if ($current eq $newval) { + $output = &mt('No changes made to management of co-author roles'); + } else { + my $chgresult = + &Apache::lonnet::put('environment',{'authormanagers' => $newval}, + $env{'user.domain'},$env{'user.name'}); + if ($chgresult eq 'ok') { + &Apache::lonnet::appenv({'environment.authormanagers' => $newval}); + my (@adds,@dels); + if ($newval eq '') { + @dels = split(/,/,$current); + } elsif ($current eq '') { + @adds = @managers; + } else { + my @old = split(/,/,$current); + my @diffs = &Apache::loncommon::compare_arrays(\@old,\@managers); + if (@diffs) { + foreach my $user (@diffs) { + if (grep(/^\Q$user\E$/,@old)) { + push(@dels,$user); + } elsif (grep(/^\Q$user\E$/,@managers)) { + push(@adds,$user); + } + } + } + } + my $key = "internal.manager./$env{'user.domain'}/$env{'user.name'}"; + if (@dels) { + foreach my $user (@dels) { + if ($user =~ /^($match_username):($match_domain)$/) { + &Apache::lonnet::del('environment',[$key],$2,$1); + } + } + } + if (@adds) { + foreach my $user (@adds) { + if ($user =~ /^($match_username):($match_domain)$/) { + &Apache::lonnet::put('environment',{$key => 1},$2,$1); + } + } + } + if ($newval eq '') { + $output = &mt('Management of co-authors set to be author-only'); + } else { + $output .= &mt('Co-authors who can manage co-author roles set to: [_1]', + '
'.join(', ',map { &Apache::loncommon::plainname(split(':',$_))." ($_)"; } @managers)); + } + } + } + } else { + $output = ''. + &mt('You do not have permission to perform this action'). + ''; + } + return $output; } # ================================================================ Main Handler @@ -3342,29 +5625,114 @@ sub handler { $r->send_http_header; return OK; } - my $context; + my ($context,$crstype,$cid,$cnum,$cdom,$allhelpitems); + if ($env{'request.course.id'}) { $context = 'course'; + $crstype = &Apache::loncommon::course_type(); } elsif ($env{'request.role'} =~ /^au\./) { $context = 'author'; + } elsif ($env{'request.role'} =~ m{^(ca|aa)\./$match_domain/$match_username$}) { + $context = 'coauthor'; } else { $context = 'domain'; } + + my ($permission,$allowed) = + &Apache::lonuserutils::get_permission($context,$crstype); + if (($context eq 'coauthor') && ($allowed)) { + $context = 'author'; + } + + if ($allowed) { + my @allhelp; + if ($context eq 'course') { + $cid = $env{'request.course.id'}; + $cdom = $env{'course.'.$cid.'.domain'}; + $cnum = $env{'course.'.$cid.'.num'}; + + if ($permission->{'cusr'}) { + push(@allhelp,'Course_Create_Class_List'); + } + if ($permission->{'view'} || $permission->{'cusr'}) { + push(@allhelp,('Course_Change_Privileges','Course_View_Class_List')); + } + if ($permission->{'custom'}) { + push(@allhelp,'Course_Editing_Custom_Roles'); + } + if ($permission->{'cusr'}) { + push(@allhelp,('Course_Add_Student','Course_Drop_Student')); + } + unless ($permission->{'cusr_section'}) { + if (&Apache::lonnet::auto_run($cnum,$cdom) && (($permission->{'cusr'}) || ($permission->{'view'}))) { + push(@allhelp,'Course_Automated_Enrollment'); + } + if (($permission->{'selfenrolladmin'}) || ($permission->{'selfenrollview'})) { + push(@allhelp,'Course_Approve_Selfenroll'); + } + } + if ($permission->{'grp_manage'}) { + push(@allhelp,'Course_Manage_Group'); + } + if ($permission->{'view'} || $permission->{'cusr'}) { + push(@allhelp,'Course_User_Logs'); + } + } elsif ($context eq 'author') { + push(@allhelp,('Author_Change_Privileges','Author_Create_Coauthor_List', + 'Author_View_Coauthor_List','Author_User_Logs')); + } elsif ($context eq 'coauthor') { + if ($permission->{'cusr'}) { + push(@allhelp,('Author_Change_Privileges','Author_Create_Coauthor_List', + 'Author_View_Coauthor_List','Author_User_Logs')); + } elsif ($permission->{'view'}) { + push(@allhelp,'Author_View_Coauthor_List'); + } + } else { + if ($permission->{'cusr'}) { + push(@allhelp,'Domain_Change_Privileges'); + if ($permission->{'activity'}) { + push(@allhelp,'Domain_User_Access_Logs'); + } + push(@allhelp,('Domain_Create_Users','Domain_View_Users_List')); + if ($permission->{'custom'}) { + push(@allhelp,'Domain_Editing_Custom_Roles'); + } + push(@allhelp,('Domain_Role_Approvals','Domain_Username_Approvals','Domain_Change_Logs')); + } elsif ($permission->{'view'}) { + push(@allhelp,'Domain_View_Privileges'); + if ($permission->{'activity'}) { + push(@allhelp,'Domain_User_Access_Logs'); + } + push(@allhelp,('Domain_View_Users_List','Domain_Change_Logs')); + } + } + if (@allhelp) { + $allhelpitems = join(',',@allhelp); + } + } + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['action','state','callingform','roletype','showrole','bulkaction','popup','phase', - 'username','domain','srchterm','srchdomain','srchin','srchby','srchtype']); + 'username','domain','srchterm','srchdomain','srchin','srchby','srchtype','queue', + 'forceedit']); &Apache::lonhtmlcommon::clear_breadcrumbs(); - if ($env{'form.action'} ne 'dateselect') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"/adm/createuser", - text=>"User Management", - help=>'Course_Create_Class_List,Course_Change_Privileges,Course_View_Class_List,Course_Editing_Custom_Roles,Course_Add_Student,Course_Drop_Student,Course_Automated_Enrollment,Course_Self_Enrollment,Course_Manage_Group'}); - } - #SD Following files not added to help, because the corresponding .tex-files seem to - #be missing: Course_Approve_Selfenroll,Course_User_Logs, - my ($permission,$allowed) = - &Apache::lonuserutils::get_permission($context); + my $args; + my $brcrum = []; + my $bread_crumbs_component = 'User Management'; + if (($env{'form.action'} ne 'dateselect') && ($env{'form.action'} ne 'displayuserreq')) { + $brcrum = [{href=>"/adm/createuser", + text=>"User Management", + help=>$allhelpitems} + ]; + } if (!$allowed) { + if ($context eq 'course') { + $r->internal_redirect('/adm/viewclasslist'); + return OK; + } elsif ($context eq 'coauthor') { + $r->internal_redirect('/adm/viewcoauthors'); + return OK; + } $env{'user.error.msg'}= "/adm/createuser:cst:0:0:Cannot create/modify user data ". "or view user status."; @@ -3374,37 +5742,83 @@ sub handler { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; + my $showcredits; + if ((($context eq 'course') && ($crstype eq 'Course')) || + ($context eq 'domain')) { + my %domdefaults = + &Apache::lonnet::get_domain_defaults($env{'request.role.domain'}); + if ($domdefaults{'officialcredits'} || $domdefaults{'unofficialcredits'}) { + $showcredits = 1; + } + } + # Main switch on form.action and form.state, as appropriate if (! exists($env{'form.action'})) { - $r->print(&header()); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); - $r->print(&print_main_menu($permission,$context)); - $r->print(&Apache::loncommon::end_page()); + $args = {bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + $r->print(&header(undef,$args)); + $r->print(&print_main_menu($permission,$context,$crstype)); } elsif ($env{'form.action'} eq 'upload' && $permission->{'cusr'}) { - $r->print(&header()); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=upload&state=', - text=>"Upload Users List"}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Upload Users List', - 'Course_Create_Class_List')); + my $helpitem = 'Course_Create_Class_List'; + if ($context eq 'author') { + $helpitem = 'Author_Create_Coauthor_List'; + } elsif ($context eq 'domain') { + $helpitem = 'Domain_Create_Users'; + } + push(@{$brcrum}, + { href => '/adm/createuser?action=upload&state=', + text => 'Upload Users List', + help => $helpitem, + }); + $bread_crumbs_component = 'Upload Users List'; + $args = {bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + $r->print(&header(undef,$args)); $r->print(''."\n"); if (! exists($env{'form.state'})) { &Apache::lonuserutils::print_first_users_upload_form($r,$context); } elsif ($env{'form.state'} eq 'got_file') { - &Apache::lonuserutils::print_upload_manager_form($r,$context, - $permission); + my $result = + &Apache::lonuserutils::print_upload_manager_form($r,$context, + $permission, + $crstype,$showcredits); + if ($result eq 'missingdata') { + delete($env{'form.state'}); + &Apache::lonuserutils::print_first_users_upload_form($r,$context); + } } elsif ($env{'form.state'} eq 'enrolling') { if ($env{'form.datatoken'}) { - &Apache::lonuserutils::upfile_drop_add($r,$context,$permission); + my $result = &Apache::lonuserutils::upfile_drop_add($r,$context, + $permission, + $showcredits); + if ($result eq 'missingdata') { + delete($env{'form.state'}); + &Apache::lonuserutils::print_first_users_upload_form($r,$context); + } elsif ($result eq 'invalidhome') { + $env{'form.state'} = 'got_file'; + delete($env{'form.lcserver'}); + my $result = + &Apache::lonuserutils::print_upload_manager_form($r,$context,$permission, + $crstype,$showcredits); + if ($result eq 'missingdata') { + delete($env{'form.state'}); + &Apache::lonuserutils::print_first_users_upload_form($r,$context); + } + } + } else { + delete($env{'form.state'}); + &Apache::lonuserutils::print_first_users_upload_form($r,$context); } } else { &Apache::lonuserutils::print_first_users_upload_form($r,$context); } - $r->print(''.&Apache::loncommon::end_page()); - } elsif ((($env{'form.action'} eq 'singleuser') || ($env{'form.action'} - eq 'singlestudent')) && ($permission->{'cusr'})) { + $r->print(''); + } elsif (((($env{'form.action'} eq 'singleuser') || ($env{'form.action'} + eq 'singlestudent')) && ($permission->{'cusr'})) || + (($env{'form.action'} eq 'singleuser') && ($permission->{'view'})) || + (($env{'form.action'} eq 'accesslogs') && ($permission->{'activity'}))) { my $phase = $env{'form.phase'}; my @search = ('srchterm','srchby','srchin','srchtype','srchdomain'); &Apache::loncreateuser::restore_prev_selections(); @@ -3413,19 +5827,25 @@ sub handler { $srch->{$item} = $env{'form.'.$item}; } if (($phase eq 'get_user_info') || ($phase eq 'userpicked') || - ($phase eq 'createnewuser')) { + ($phase eq 'createnewuser') || ($phase eq 'activity')) { if ($env{'form.phase'} eq 'createnewuser') { my $response; if ($env{'form.srchterm'} !~ /^$match_username$/) { - my $response = &mt('You must specify a valid username. Only the following are allowed: letters numbers - . @'); + my $response = + '' + .&mt('You must specify a valid username. Only the following are allowed:' + .' letters numbers - . @') + .''; $env{'form.phase'} = ''; - &print_username_entry_form($r,$context,$response,$srch); + &print_username_entry_form($r,$context,$response,$srch,undef, + $crstype,$brcrum,$permission); } else { my $ccuname =&LONCAPA::clean_username($srch->{'srchterm'}); my $ccdomain=&LONCAPA::clean_domain($srch->{'srchdomain'}); &print_user_modification_page($r,$ccuname,$ccdomain, $srch,$response,$context, - $permission); + $permission,$crstype,$brcrum, + $showcredits); } } elsif ($env{'form.phase'} eq 'get_user_info') { my ($currstate,$response,$forcenewuser,$results) = @@ -3435,9 +5855,10 @@ sub handler { } if ($currstate eq 'select') { &print_user_selection_page($r,$response,$srch,$results, - \@search,$context); - } elsif ($currstate eq 'modify') { - my ($ccuname,$ccdomain); + \@search,$context,undef,$crstype, + $brcrum); + } elsif (($currstate eq 'modify') || ($env{'form.action'} eq 'accesslogs')) { + my ($ccuname,$ccdomain,$uhome); if (($srch->{'srchby'} eq 'uname') && ($srch->{'srchtype'} eq 'exact')) { $ccuname = $srch->{'srchterm'}; @@ -3448,202 +5869,754 @@ sub handler { } $ccuname =&LONCAPA::clean_username($ccuname); $ccdomain=&LONCAPA::clean_domain($ccdomain); - if ($env{'form.forcenewuser'}) { - $response = ''; + if ($env{'form.action'} eq 'accesslogs') { + my $uhome; + if (($ccuname ne '') && ($ccdomain ne '')) { + $uhome = &Apache::lonnet::homeserver($ccuname,$ccdomain); + } + if (($uhome eq '') || ($uhome eq 'no_host')) { + $env{'form.phase'} = ''; + undef($forcenewuser); + #if ($response) { + # unless ($response =~ m{\Q

\E$}) { + # $response .= '

'; + # } + #} + &print_username_entry_form($r,$context,$response,$srch, + $forcenewuser,$crstype,$brcrum, + $permission); + } else { + &print_useraccesslogs_display($r,$ccuname,$ccdomain,$permission,$brcrum); + } + } else { + if ($env{'form.forcenewuser'}) { + $response = ''; + } + &print_user_modification_page($r,$ccuname,$ccdomain, + $srch,$response,$context, + $permission,$crstype,$brcrum); } - &print_user_modification_page($r,$ccuname,$ccdomain, - $srch,$response,$context, - $permission); } elsif ($currstate eq 'query') { - &print_user_query_page($r,'createuser'); + &print_user_query_page($r,'createuser',$brcrum); } else { $env{'form.phase'} = ''; &print_username_entry_form($r,$context,$response,$srch, - $forcenewuser); + $forcenewuser,$crstype,$brcrum, + $permission); } } elsif ($env{'form.phase'} eq 'userpicked') { my $ccuname = &LONCAPA::clean_username($env{'form.seluname'}); my $ccdomain = &LONCAPA::clean_domain($env{'form.seludom'}); - &print_user_modification_page($r,$ccuname,$ccdomain,$srch,'', - $context,$permission); + if ($env{'form.action'} eq 'accesslogs') { + &print_useraccesslogs_display($r,$ccuname,$ccdomain,$permission,$brcrum); + } else { + &print_user_modification_page($r,$ccuname,$ccdomain,$srch,'', + $context,$permission,$crstype, + $brcrum); + } + } elsif ($env{'form.action'} eq 'accesslogs') { + my $ccuname = &LONCAPA::clean_username($env{'form.accessuname'}); + my $ccdomain = &LONCAPA::clean_domain($env{'form.accessudom'}); + &print_useraccesslogs_display($r,$ccuname,$ccdomain,$permission,$brcrum); } } elsif ($env{'form.phase'} eq 'update_user_data') { - &update_user_data($r,$context); + &update_user_data($r,$context,$crstype,$brcrum,$showcredits,$permission); } else { - &print_username_entry_form($r,$context,undef,$srch); + &print_username_entry_form($r,$context,undef,$srch,undef,$crstype, + $brcrum,$permission); } } elsif ($env{'form.action'} eq 'custom' && $permission->{'custom'}) { + my $prefix; if ($env{'form.phase'} eq 'set_custom_roles') { - &set_custom_role($r,$context); + &set_custom_role($r,$context,$brcrum,$prefix,$permission); } else { - &custom_role_editor($r); + &custom_role_editor($r,$context,$brcrum,$prefix,$permission); } + } elsif (($env{'form.action'} eq 'processauthorreq') && + ($permission->{'cusr'}) && + (&Apache::lonnet::allowed('cau',$env{'request.role.domain'}))) { + push(@{$brcrum}, + {href => '/adm/createuser?action=processauthorreq', + text => 'Authoring Space requests', + help => 'Domain_Role_Approvals'}); + $bread_crumbs_component = 'Authoring requests'; + if ($env{'form.state'} eq 'done') { + push(@{$brcrum}, + {href => '/adm/createuser?action=authorreqqueue', + text => 'Result', + help => 'Domain_Role_Approvals'}); + $bread_crumbs_component = 'Authoring request result'; + } + $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + my $js = &usernamerequest_javascript(); + $r->print(&header(&add_script($js),$args)); + if (!exists($env{'form.state'})) { + $r->print(&Apache::loncoursequeueadmin::display_queued_requests('requestauthor', + $env{'request.role.domain'})); + } elsif ($env{'form.state'} eq 'done') { + $r->print('

'.&mt('Authoring request processing').'

'."\n"); + $r->print(&Apache::loncoursequeueadmin::update_request_queue('requestauthor', + $env{'request.role.domain'})); + } + } elsif (($env{'form.action'} eq 'processusernamereq') && + ($permission->{'cusr'}) && + (&Apache::lonnet::allowed('cau',$env{'request.role.domain'}))) { + push(@{$brcrum}, + {href => '/adm/createuser?action=processusernamereq', + text => 'LON-CAPA account requests', + help => 'Domain_Username_Approvals'}); + $bread_crumbs_component = 'Account requests'; + if ($env{'form.state'} eq 'done') { + push(@{$brcrum}, + {href => '/adm/createuser?action=usernamereqqueue', + text => 'Result', + help => 'Domain_Username_Approvals'}); + $bread_crumbs_component = 'LON-CAPA account request result'; + } + $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + my $js = &usernamerequest_javascript(); + $r->print(&header(&add_script($js),$args)); + if (!exists($env{'form.state'})) { + $r->print(&Apache::loncoursequeueadmin::display_queued_requests('requestusername', + $env{'request.role.domain'})); + } elsif ($env{'form.state'} eq 'done') { + $r->print('

'.&mt('LON-CAPA account request processing').'

'."\n"); + $r->print(&Apache::loncoursequeueadmin::update_request_queue('requestusername', + $env{'request.role.domain'})); + } + } elsif (($env{'form.action'} eq 'displayuserreq') && + ($permission->{'cusr'})) { + my $dom = $env{'form.domain'}; + my $uname = $env{'form.username'}; + my $warning; + if (($dom =~ /^$match_domain$/) && (&Apache::lonnet::domain($dom) ne '')) { + if (($dom eq $env{'request.role.domain'}) && (&Apache::lonnet::allowed('ccc',$dom))) { + if (($uname =~ /^$match_username$/) && ($env{'form.queue'} eq 'approval')) { + my $uhome = &Apache::lonnet::homeserver($uname,$dom); + if ($uhome eq 'no_host') { + my $queue = $env{'form.queue'}; + my $reqkey = &escape($uname).'_'.$queue; + my $namespace = 'usernamequeue'; + my $domconfig = &Apache::lonnet::get_domainconfiguser($dom); + my %queued = + &Apache::lonnet::get($namespace,[$reqkey],$dom,$domconfig); + unless ($queued{$reqkey}) { + $warning = &mt('No information was found for this LON-CAPA account request.'); + } + } else { + $warning = &mt('A LON-CAPA account already exists for the requested username and domain.'); + } + } else { + $warning = &mt('LON-CAPA account request status check is for an invalid username.'); + } + } else { + $warning = &mt('You do not have rights to view LON-CAPA account requests in the domain specified.'); + } + } else { + $warning = &mt('LON-CAPA account request status check is for an invalid domain.'); + } + my $args = { only_body => 1 }; + $r->print(&header(undef,$args). + '

'.&mt('LON-CAPA Account Request Details').'

'); + if ($warning ne '') { + $r->print('
'.$warning.'
'); + } else { + my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info(); + my $domconfiguser = &Apache::lonnet::get_domainconfiguser($dom); + my %domconfig = &Apache::lonnet::get_dom('configuration',['usercreation'],$dom); + if (ref($domconfig{'usercreation'}) eq 'HASH') { + if (ref($domconfig{'usercreation'}{'cancreate'}) eq 'HASH') { + if (ref($domconfig{'usercreation'}{'cancreate'}{'emailusername'}) eq 'HASH') { + my %info = + &Apache::lonnet::get('nohist_requestedusernames',[$uname],$dom,$domconfiguser); + if (ref($info{$uname}) eq 'HASH') { + my $usertype = $info{$uname}{'inststatus'}; + unless ($usertype) { + $usertype = 'default'; + } + my ($showstatus,$showemail,$pickstart); + my $numextras = 0; + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($dom); + if ((ref($types) eq 'ARRAY') && (@{$types} > 0)) { + if (ref($usertypes) eq 'HASH') { + if ($usertypes->{$usertype}) { + $showstatus = $usertypes->{$usertype}; + } else { + $showstatus = $othertitle; + } + if ($showstatus) { + $numextras ++; + } + } + } + if (($info{$uname}{'email'} ne '') && ($info{$uname}{'email'} ne $uname)) { + $showemail = $info{$uname}{'email'}; + $numextras ++; + } + if (ref($domconfig{'usercreation'}{'cancreate'}{'emailusername'}{$usertype}) eq 'HASH') { + if ((ref($infofields) eq 'ARRAY') && (ref($infotitles) eq 'HASH')) { + $pickstart = 1; + $r->print('
'.&Apache::lonhtmlcommon::start_pick_box()); + my ($num,$count); + $count = scalar(keys(%{$domconfig{'usercreation'}{'cancreate'}{'emailusername'}{$usertype}})); + $count += $numextras; + foreach my $field (@{$infofields}) { + next unless ($domconfig{'usercreation'}{'cancreate'}{'emailusername'}{$usertype}{$field}); + next unless ($infotitles->{$field}); + $r->print(&Apache::lonhtmlcommon::row_title($infotitles->{$field}). + $info{$uname}{$field}); + $num ++; + unless ($count == $num) { + $r->print(&Apache::lonhtmlcommon::row_closure()); + } + } + } + } + if ($numextras) { + unless ($pickstart) { + $r->print('
'.&Apache::lonhtmlcommon::start_pick_box()); + $pickstart = 1; + } + if ($showemail) { + my $closure = ''; + unless ($showstatus) { + $closure = 1; + } + $r->print(&Apache::lonhtmlcommon::row_title(&mt('E-mail address')). + $showemail. + &Apache::lonhtmlcommon::row_closure($closure)); + } + if ($showstatus) { + $r->print(&Apache::lonhtmlcommon::row_title(&mt('Status type[_1](self-reported)','
')). + $showstatus. + &Apache::lonhtmlcommon::row_closure(1)); + } + } + if ($pickstart) { + $r->print(&Apache::lonhtmlcommon::end_pick_box().'
'); + } else { + $r->print('
'.&mt('No information to display for this account request.').'
'); + } + } else { + $r->print('
'.&mt('No information available for this account request.').'
'); + } + } + } + } + } + $r->print(&close_popup_form()); } elsif (($env{'form.action'} eq 'listusers') && ($permission->{'view'} || $permission->{'cusr'})) { + my $helpitem = 'Course_View_Class_List'; + if ($context eq 'author') { + $helpitem = 'Author_View_Coauthor_List'; + } elsif ($context eq 'domain') { + $helpitem = 'Domain_View_Users_List'; + } if ($env{'form.phase'} eq 'bulkchange') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=listusers', - text=>"List Users"}, - {href=>"/adm/createuser", - text=>"Result"}); + push(@{$brcrum}, + {href => '/adm/createuser?action=listusers', + text => "List Users"}, + {href => "/adm/createuser", + text => "Result", + help => $helpitem}); + $bread_crumbs_component = 'Update Users'; + $args = {bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + $r->print(&header(undef,$args)); my $setting = $env{'form.roletype'}; my $choice = $env{'form.bulkaction'}; - $r->print(&header()); - $r->print(&Apache::lonhtmlcommon::breadcrumbs("Update Users", - 'Course_View_Class_List')); if ($permission->{'cusr'}) { - &Apache::lonuserutils::update_user_list($r,$context,$setting,$choice); - $r->print(&Apache::loncommon::end_page()); + &Apache::lonuserutils::update_user_list($r,$context,$setting,$choice,$crstype); } else { $r->print(&mt('You are not authorized to make bulk changes to user roles')); $r->print('

'.&mt('Display User Lists').''); - $r->print(&Apache::loncommon::end_page()); } } else { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=listusers', - text=>"List Users"}); + push(@{$brcrum}, + {href => '/adm/createuser?action=listusers', + text => "List Users", + help => $helpitem}); + $bread_crumbs_component = 'List Users'; + $args = {bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; my ($cb_jscript,$jscript,$totcodes,$codetitles,$idlist,$idlist_titles); my $formname = 'studentform'; - if ($context eq 'domain' && $env{'form.roletype'} eq 'course') { - ($cb_jscript,$jscript,$totcodes,$codetitles,$idlist,$idlist_titles) = - &Apache::lonuserutils::courses_selector($env{'request.role.domain'}, - $formname); - $jscript .= &verify_user_display(); + my $hidecall = "hide_searching();"; + if (($context eq 'domain') && (($env{'form.roletype'} eq 'course') || + ($env{'form.roletype'} eq 'community'))) { + if ($env{'form.roletype'} eq 'course') { + ($cb_jscript,$jscript,$totcodes,$codetitles,$idlist,$idlist_titles) = + &Apache::lonuserutils::courses_selector($env{'request.role.domain'}, + $formname); + } elsif ($env{'form.roletype'} eq 'community') { + $cb_jscript = + &Apache::loncommon::coursebrowser_javascript($env{'request.role.domain'}); + my %elements = ( + coursepick => 'radio', + coursetotal => 'text', + courselist => 'text', + ); + $jscript = &Apache::lonhtmlcommon::set_form_elements(\%elements); + } + $jscript .= &verify_user_display($context)."\n". + &Apache::loncommon::check_uncheck_jscript(); my $js = &add_script($jscript).$cb_jscript; my $loadcode = &Apache::lonuserutils::course_selector_loadcode($formname); if ($loadcode ne '') { - $r->print(&header($js,{'onload' => $loadcode,})); + $args->{add_entries} = {onload => "$loadcode;$hidecall"}; } else { - $r->print(&header($js)); + $args->{add_entries} = {onload => $hidecall}; } + $r->print(&header($js,$args)); } else { - $r->print(&header(&add_script(&verify_user_display()))); + $args->{add_entries} = {onload => $hidecall}; + $jscript = &verify_user_display($context). + &Apache::loncommon::check_uncheck_jscript(); + $r->print(&header(&add_script($jscript),$args)); } - $r->print(&Apache::lonhtmlcommon::breadcrumbs("List Users", - 'Course_View_Class_List')); &Apache::lonuserutils::print_userlist($r,undef,$permission,$context, - $formname,$totcodes,$codetitles,$idlist,$idlist_titles); - $r->print(&Apache::loncommon::end_page()); + $formname,$totcodes,$codetitles,$idlist,$idlist_titles, + $showcredits); } } elsif ($env{'form.action'} eq 'drop' && $permission->{'cusr'}) { - $r->print(&header()); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=drop', - text=>"Drop Students"}); + my $brtext; + if ($crstype eq 'Community') { + $brtext = 'Drop Members'; + } else { + $brtext = 'Drop Students'; + } + push(@{$brcrum}, + {href => '/adm/createuser?action=drop', + text => $brtext, + help => 'Course_Drop_Student'}); + if ($env{'form.state'} eq 'done') { + push(@{$brcrum}, + {href=>'/adm/createuser?action=drop', + text=>"Result"}); + } + $bread_crumbs_component = $brtext; + $args = {bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + $r->print(&header(undef,$args)); if (!exists($env{'form.state'})) { - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students', - 'Course_Drop_Student')); - - &Apache::lonuserutils::print_drop_menu($r,$context,$permission); + &Apache::lonuserutils::print_drop_menu($r,$context,$permission,$crstype); } elsif ($env{'form.state'} eq 'done') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=drop', - text=>"Result"}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students', - 'Course_Drop_Student')); &Apache::lonuserutils::update_user_list($r,$context,undef, $env{'form.action'}); } - $r->print(&Apache::loncommon::end_page()); } elsif ($env{'form.action'} eq 'dateselect') { if ($permission->{'cusr'}) { - $r->print(&header(undef,undef,{'no_nav_bar' => 1}). - &Apache::lonuserutils::date_section_selector($context, - $permission). - &Apache::loncommon::end_page()); - } else { - $r->print(&header(). - ''.&mt('You do not have permission to modify dates or sections for users').''. - &Apache::loncommon::end_page()); + $r->print(&header(undef,{'no_nav_bar' => 1}). + &Apache::lonuserutils::date_section_selector($context,$permission, + $crstype,$showcredits)); + } else { + $r->print(&header(undef,{'no_nav_bar' => 1}). + ''.&mt('You do not have permission to modify dates or sections for users').''); } } elsif ($env{'form.action'} eq 'selfenroll') { - $r->print(&header()); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=selfenroll', - text=>"Configure Self-enrollment"}); - if (!exists($env{'form.state'})) { - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Configure Self-enrollment', - 'Course_Self_Enrollment')); - $r->print('

'.&mt('Self-enrollment with a student role').'

'."\n"); - &print_selfenroll_menu($r,$context,$permission); - } elsif ($env{'form.state'} eq 'done') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=selfenroll', - text=>"Result"}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Self-enrollment result', - 'Course_Self_Enrollment')); + my %currsettings; + if ($permission->{selfenrolladmin} || $permission->{selfenrollview}) { + %currsettings = ( + selfenroll_types => $env{'course.'.$cid.'.internal.selfenroll_types'}, + selfenroll_registered => $env{'course.'.$cid.'.internal.selfenroll_registered'}, + selfenroll_section => $env{'course.'.$cid.'.internal.selfenroll_section'}, + selfenroll_notifylist => $env{'course.'.$cid.'.internal.selfenroll_notifylist'}, + selfenroll_approval => $env{'course.'.$cid.'.internal.selfenroll_approval'}, + selfenroll_limit => $env{'course.'.$cid.'.internal.selfenroll_limit'}, + selfenroll_cap => $env{'course.'.$cid.'.internal.selfenroll_cap'}, + selfenroll_start_date => $env{'course.'.$cid.'.internal.selfenroll_start_date'}, + selfenroll_end_date => $env{'course.'.$cid.'.internal.selfenroll_end_date'}, + selfenroll_start_access => $env{'course.'.$cid.'.internal.selfenroll_start_access'}, + selfenroll_end_access => $env{'course.'.$cid.'.internal.selfenroll_end_access'}, + default_enrollment_start_date => $env{'course.'.$cid.'.default_enrollment_start_date'}, + default_enrollment_end_date => $env{'course.'.$cid.'.default_enrollment_end_date'}, + uniquecode => $env{'course.'.$cid.'.internal.uniquecode'}, + ); + } + if ($permission->{selfenrolladmin}) { + push(@{$brcrum}, + {href => '/adm/createuser?action=selfenroll', + text => "Configure Self-enrollment", + help => 'Course_Self_Enrollment'}); + if (!exists($env{'form.state'})) { + $args = { bread_crumbs => $brcrum, + bread_crumbs_component => 'Configure Self-enrollment'}; + $r->print(&header(undef,$args)); + $r->print('

'.&mt('Self-enrollment with a student role').'

'."\n"); + &print_selfenroll_menu($r,'course',$cid,$cdom,$cnum,\%currsettings); + } elsif ($env{'form.state'} eq 'done') { + push (@{$brcrum}, + {href=>'/adm/createuser?action=selfenroll', + text=>"Result"}); + $args = { bread_crumbs => $brcrum, + bread_crumbs_component => 'Self-enrollment result'}; + $r->print(&header(undef,$args)); + $r->print('

'.&mt('Self-enrollment with a student role').'

'."\n"); + &update_selfenroll_config($r,$cid,$cdom,$cnum,$context,$crstype,\%currsettings); + } + } elsif ($permission->{selfenrollview}) { + push(@{$brcrum}, + {href => '/adm/createuser?action=selfenroll', + text => "View Self-enrollment configuration", + help => 'Course_Self_Enrollment'}); + $args = { bread_crumbs => $brcrum, + bread_crumbs_component => 'Self-enrollment Settings'}; + $r->print(&header(undef,$args)); $r->print('

'.&mt('Self-enrollment with a student role').'

'."\n"); - &update_selfenroll_config($r,$context,$permission); + &print_selfenroll_menu($r,'course',$cid,$cdom,$cnum,\%currsettings,'',1); + } else { + $r->print(&header(undef,{'no_nav_bar' => 1}). + ''.&mt('You do not have permission to configure self-enrollment').''); } - $r->print(&Apache::loncommon::end_page()); } elsif ($env{'form.action'} eq 'selfenrollqueue') { - $r->print(&header()); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=selfenrollqueue', - text=>"Enrollment requests"}); - my $cid = $env{'request.course.id'}; - my $cdom = $env{'course.'.$cid.'.domain'}; - my $cnum = $env{'course.'.$cid.'.num'}; - if (!exists($env{'form.state'})) { - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment requests', - 'Course_SelfEnrollment_Approval')); - $r->print('

'.&mt('Pending enrollment requests').'

'."\n"); - &display_selfenroll_queue($r,$context,$permission,$cnum,$cdom); - } elsif ($env{'form.state'} eq 'done') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=selfenrollqueue', - text=>"Result"}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment result', - 'Course_Self_Enrollment')); - $r->print('

'.&mt('Enrollment request processing').'

'."\n"); - &update_selfenroll_queue($r,$context,$permission,$cid,$cnum,$cdom); + if ($permission->{selfenrolladmin}) { + push(@{$brcrum}, + {href => '/adm/createuser?action=selfenrollqueue', + text => 'Enrollment requests', + help => 'Course_Approve_Selfenroll'}); + $bread_crumbs_component = 'Enrollment requests'; + if ($env{'form.state'} eq 'done') { + push(@{$brcrum}, + {href => '/adm/createuser?action=selfenrollqueue', + text => 'Result', + help => 'Course_Approve_Selfenroll'}); + $bread_crumbs_component = 'Enrollment result'; + } + $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + $r->print(&header(undef,$args)); + my $coursedesc = $env{'course.'.$cid.'.description'}; + if (!exists($env{'form.state'})) { + $r->print('

'.&mt('Pending enrollment requests').'

'."\n"); + $r->print(&Apache::loncoursequeueadmin::display_queued_requests($context, + $cdom,$cnum)); + } elsif ($env{'form.state'} eq 'done') { + $r->print('

'.&mt('Enrollment request processing').'

'."\n"); + $r->print(&Apache::loncoursequeueadmin::update_request_queue($context, + $cdom,$cnum,$coursedesc)); + } + } else { + $r->print(&header(undef,{'no_nav_bar' => 1}). + ''.&mt('You do not have permission to manage self-enrollment').''); } - $r->print(&Apache::loncommon::end_page()); } elsif ($env{'form.action'} eq 'changelogs') { - $r->print(&header()); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/createuser?action=changelogs', - text=>"User Management Logs"}); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Changes', - 'Course_User_Logs')); - &print_userchangelogs_display($r,$context,$permission); - $r->print(&Apache::loncommon::end_page()); - } else { - $r->print(&header()); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management')); - $r->print(&print_main_menu($permission,$context)); - $r->print(&Apache::loncommon::end_page()); + if ($permission->{cusr} || $permission->{view}) { + &print_userchangelogs_display($r,$context,$permission,$brcrum); + } else { + $r->print(&header(undef,{'no_nav_bar' => 1}). + ''.&mt('You do not have permission to view change logs').''); + } + } elsif ($env{'form.action'} eq 'helpdesk') { + if (($permission->{'owner'} || $permission->{'co-owner'}) && + ($permission->{'cusr'} || $permission->{'view'})) { + if ($env{'form.state'} eq 'process') { + if ($permission->{'owner'}) { + &update_helpdeskaccess($r,$permission,$brcrum); + } else { + &print_helpdeskaccess_display($r,$permission,$brcrum); + } + } else { + &print_helpdeskaccess_display($r,$permission,$brcrum); + } + } else { + $r->print(&header(undef,{'no_nav_bar' => 1}). + ''.&mt('You do not have permission to view helpdesk access').''); + } + } elsif ($env{'form.action'} eq 'rolerequests') { + if ($permission->{cusr} || $permission->{view}) { + &print_queued_roles($r,$context,$permission,$brcrum); + } + } elsif ($env{'form.action'} eq 'queuedroles') { + if (($permission->{cusr}) && ($context eq 'domain')) { + if (&show_role_requests($context,$env{'request.role.domain'})) { + if ($env{'form.state'} eq 'done') { + &process_pendingroles($r,$context,$permission,$brcrum); + } else { + &print_pendingroles($r,$context,$permission,$brcrum); + } + } else { + $r->print(&header(undef,{'no_nav_bar' => 1}). + ''.&mt('Domain coordinator approval of requests from other domains for assignment of roles to users from this domain not in use.').''); + } + } else { + $r->print(&header(undef,{'no_nav_bar' => 1}). + ''.&mt('You do not have permission to view queued requests from other domains for assignment of roles to users from this domain.').''); + } + } elsif ($env{'form.action'} eq 'camanagers') { + if (($permission->{cusr}) && ($context eq 'author')) { + push(@{$brcrum}, + {href => '/adm/createuser?action=camanagers', + text => 'Co-authors who manage', + help => 'Author_Manage_Coauthors'}); + if ($env{'form.state'} eq 'process') { + push(@{$brcrum}, + {href => '/adm/createuser?action=camanagers', + text => 'Result', + help => 'Author_Manage_Coauthors'}); + } + $args = { bread_crumbs => $brcrum }; + $r->print(&header(undef,$args)); + my $coursedesc = $env{'course.'.$cid.'.description'}; + if (!exists($env{'form.state'})) { + $r->print('

'.&mt('Co-author Management').'

'."\n". + &display_coauthor_managers($permission)); + } elsif ($env{'form.state'} eq 'process') { + $r->print('

'.&mt('Co-author Management Update Result').'

'."\n". + &update_coauthor_managers($permission)); + } + } + } elsif (($env{'form.action'} eq 'calist') && ($context eq 'author')) { + if ($permission->{'cusr'}) { + my ($role,$audom,$auname,$canview,$canedit) = + &Apache::lonviewcoauthors::get_allowable(); + if (($canedit) && ($env{'form.forceedit'})) { + &Apache::lonviewcoauthors::get_editor_crumbs($brcrum,'/adm/createuser'); + my $args = { 'bread_crumbs' => $brcrum }; + $r->print(&Apache::loncommon::start_page('Configure co-author listing',undef, + $args). + &Apache::lonviewcoauthors::edit_settings($audom,$auname,$role, + '/adm/createuser')); + } else { + push(@{$brcrum}, + {href => '/adm/createuser?action=calist', + text => 'Coauthor-viewable list', + help => 'Author_List_Coauthors'}); + my $args = { 'bread_crumbs' => $brcrum }; + $r->print(&Apache::loncommon::start_page('Coauthor-viewable list',undef, + $args)); + my %viewsettings = + &Apache::lonviewcoauthors::retrieve_view_settings($auname,$audom,$role); + if ($viewsettings{'show'} eq 'none') { + $r->print('

'.&mt('Coauthor-viewable listing').'

'. + '

'. + &mt('Listing of co-authors not enabled for this Authoring Space'). + '

'); + } else { + &Apache::lonviewcoauthors::print_coauthors($r,$auname,$audom,$role, + '/adm/createuser',\%viewsettings); + } + } + } else { + $r->internal_redirect('/adm/viewcoauthors'); + return OK; + } + } else { + $bread_crumbs_component = 'User Management'; + $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + $r->print(&header(undef,$args)); + $r->print(&print_main_menu($permission,$context,$crstype)); } + $r->print(&Apache::loncommon::end_page()); return OK; } sub header { - my ($jscript,$loaditems,$args) = @_; + my ($jscript,$args) = @_; my $start_page; - if (ref($loaditems) eq 'HASH') { - $start_page=&Apache::loncommon::start_page('User Management',$jscript,{'add_entries' => $loaditems}); - } else { + if (ref($args) eq 'HASH') { $start_page=&Apache::loncommon::start_page('User Management',$jscript,$args); + } else { + $start_page=&Apache::loncommon::start_page('User Management',$jscript); } return $start_page; } sub add_script { my ($js) = @_; - return ''; + return ''."\n"; +} + +sub usernamerequest_javascript { + my $js = <
+ +

+END } sub verify_user_display { + my ($context) = @_; + my %lt = &Apache::lonlocal::texthash ( + course => 'course(s): description, section(s), status', + community => 'community(s): description, section(s), status', + author => 'author', + ); + my $photos; + if (($context eq 'course') && $env{'request.course.id'}) { + $photos = $env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}; + } my $output = <<"END"; +function hide_searching() { + if (document.getElementById('searching')) { + document.getElementById('searching').style.display = 'none'; + } + return; +} + function display_update() { document.studentform.action.value = 'listusers'; document.studentform.phase.value = 'display'; document.studentform.submit(); } +function updateCols(caller) { + var context = '$context'; + var photos = '$photos'; + if (caller == 'Status') { + if ((context == 'domain') && + ((document.studentform.roletype.options[document.studentform.roletype.selectedIndex].value == 'course') || + (document.studentform.roletype.options[document.studentform.roletype.selectedIndex].value == 'community'))) { + document.getElementById('showcolstatus').checked = false; + document.getElementById('showcolstatus').disabled = 'disabled'; + document.getElementById('showcolstart').checked = false; + document.getElementById('showcolend').checked = false; + } else { + if (document.studentform.Status.options[document.studentform.Status.selectedIndex].value == 'Any') { + document.getElementById('showcolstatus').checked = true; + document.getElementById('showcolstatus').disabled = ''; + document.getElementById('showcolstart').checked = true; + document.getElementById('showcolend').checked = true; + } else { + document.getElementById('showcolstatus').checked = false; + document.getElementById('showcolstatus').disabled = 'disabled'; + document.getElementById('showcolstart').checked = false; + document.getElementById('showcolend').checked = false; + } + if (context == 'author') { + if (document.studentform.Status.options[document.studentform.Status.selectedIndex].value == 'Expired') { + document.getElementById('showcolmanager').checked = false; + document.getElementById('showcolmanager').disabled = 'disabled'; + } else if (document.studentform.showrole.options[document.studentform.showrole.selectedIndex].value != 'aa') { + document.getElementById('showcolmanager').checked = true; + document.getElementById('showcolmanager').disabled = ''; + } + } + } + } + if (caller == 'output') { + if (photos == 1) { + if (document.getElementById('showcolphoto')) { + var photoitem = document.getElementById('showcolphoto'); + if (document.studentform.output.options[document.studentform.output.selectedIndex].value == 'html') { + photoitem.checked = true; + photoitem.disabled = ''; + } else { + photoitem.checked = false; + photoitem.disabled = 'disabled'; + } + } + } + } + if (caller == 'showrole') { + if ((document.studentform.showrole.options[document.studentform.showrole.selectedIndex].value == 'Any') || + (document.studentform.showrole.options[document.studentform.showrole.selectedIndex].value == 'cr')) { + document.getElementById('showcolrole').checked = true; + document.getElementById('showcolrole').disabled = ''; + } else { + document.getElementById('showcolrole').checked = false; + document.getElementById('showcolrole').disabled = 'disabled'; + } + if (context == 'domain') { + var quotausageshow = 0; + if ((document.studentform.roletype.options[document.studentform.roletype.selectedIndex].value == 'course') || + (document.studentform.roletype.options[document.studentform.roletype.selectedIndex].value == 'community')) { + document.getElementById('showcolstatus').checked = false; + document.getElementById('showcolstatus').disabled = 'disabled'; + document.getElementById('showcolstart').checked = false; + document.getElementById('showcolend').checked = false; + } else { + if (document.studentform.Status.options[document.studentform.Status.selectedIndex].value == 'Any') { + document.getElementById('showcolstatus').checked = true; + document.getElementById('showcolstatus').disabled = ''; + document.getElementById('showcolstart').checked = true; + document.getElementById('showcolend').checked = true; + } + } + if (document.studentform.roletype.options[document.studentform.roletype.selectedIndex].value == 'domain') { + document.getElementById('showcolextent').disabled = 'disabled'; + document.getElementById('showcolextent').checked = 'false'; + document.getElementById('showextent').style.display='none'; + document.getElementById('showcoltextextent').innerHTML = ''; + if ((document.studentform.showrole.options[document.studentform.showrole.selectedIndex].value == 'au') || + (document.studentform.showrole.options[document.studentform.showrole.selectedIndex].value == 'Any')) { + if (document.getElementById('showcolauthorusage')) { + document.getElementById('showcolauthorusage').disabled = ''; + } + if (document.getElementById('showcolauthorquota')) { + document.getElementById('showcolauthorquota').disabled = ''; + } + quotausageshow = 1; + } + } else { + document.getElementById('showextent').style.display='block'; + document.getElementById('showextent').style.textAlign='left'; + document.getElementById('showextent').style.textFace='normal'; + if (document.studentform.roletype.options[document.studentform.roletype.selectedIndex].value == 'author') { + document.getElementById('showcolextent').disabled = ''; + document.getElementById('showcolextent').checked = 'true'; + document.getElementById('showcoltextextent').innerHTML="$lt{'author'}"; + } else { + document.getElementById('showcolextent').disabled = ''; + document.getElementById('showcolextent').checked = 'true'; + if (document.studentform.roletype.options[document.studentform.roletype.selectedIndex].value == 'community') { + document.getElementById('showcoltextextent').innerHTML="$lt{'community'}"; + } else { + document.getElementById('showcoltextextent').innerHTML="$lt{'course'}"; + } + } + } + if (quotausageshow == 0) { + if (document.getElementById('showcolauthorusage')) { + document.getElementById('showcolauthorusage').checked = false; + document.getElementById('showcolauthorusage').disabled = 'disabled'; + } + if (document.getElementById('showcolauthorquota')) { + document.getElementById('showcolauthorquota').checked = false; + document.getElementById('showcolauthorquota').disabled = 'disabled'; + } + } + } + if (context == 'author') { + if (document.studentform.showrole.options[document.studentform.showrole.selectedIndex].value == 'aa') { + document.getElementById('showcolmanager').checked = false; + document.getElementById('showcolmanager').disabled = 'disabled'; + } else if (document.studentform.Status.options[document.studentform.Status.selectedIndex].value != 'Expired') { + document.getElementById('showcolmanager').checked = true; + document.getElementById('showcolmanager').disabled = ''; + } + } + } + return; +} + END return $output; @@ -3653,123 +6626,343 @@ END ############################################################### # Menu Phase One sub print_main_menu { - my ($permission,$context) = @_; + my ($permission,$context,$crstype) = @_; + my $linkcontext = $context; + my $stuterm = lc(&Apache::lonnet::plaintext('st',$crstype)); + if (($context eq 'course') && ($crstype eq 'Community')) { + $linkcontext = lc($crstype); + $stuterm = 'Members'; + } my %links = ( - domain => { - upload => 'Upload a File of Users', - singleuser => 'Add/Modify a Single User', - listusers => 'Manage Multiple Users', - }, - author => { - upload => 'Upload a File of Co-authors', - singleuser => 'Add/Modify a Single Co-author', - listusers => 'Display Co-authors and Manage Multiple Users', - }, - course => { - upload => 'Upload a File of Course Users', - singleuser => 'Add/Modify a Single Course User', - listusers => 'Display Class Lists and Manage Multiple Users', - }, + domain => { + upload => 'Upload a File of Users', + singleuser => 'Add/Modify a User', + listusers => 'Manage Users', + }, + author => { + upload => 'Upload a File of Co-authors', + singleuser => 'Add/Modify a Co-author', + listusers => 'Manage Co-authors', + }, + course => { + upload => 'Upload a File of Course Users', + singleuser => 'Add/Modify a Course User', + listusers => 'List and Modify Multiple Course Users', + }, + community => { + upload => 'Upload a File of Community Users', + singleuser => 'Add/Modify a Community User', + listusers => 'List and Modify Multiple Community Users', + }, + ); + my %linktitles = ( + domain => { + singleuser => 'Add a user to the domain, and/or a course or community in the domain.', + listusers => 'Show and manage users in this domain.', + }, + author => { + singleuser => 'Add a user with a co- or assistant author role.', + listusers => 'Show and manage co- or assistant authors.', + }, + course => { + singleuser => 'Add a user with a certain role to this course.', + listusers => 'Show and manage users in this course.', + }, + community => { + singleuser => 'Add a user with a certain role to this community.', + listusers => 'Show and manage users in this community.', + }, ); - my @menu = - ( - { text => $links{$context}{'upload'}, - help => 'Course_Create_Class_List', - action => 'upload', - permission => $permission->{'cusr'}, + if ($linkcontext eq 'domain') { + unless ($permission->{'cusr'}) { + $links{'domain'}{'singleuser'} = 'View a User'; + $linktitles{'domain'}{'singleuser'} = 'View information about a user in the domain'; + } + } elsif ($linkcontext eq 'course') { + unless ($permission->{'cusr'}) { + $links{'course'}{'singleuser'} = 'View a Course User'; + $linktitles{'course'}{'singleuser'} = 'View information about a user in this course'; + $links{'course'}{'listusers'} = 'List Course Users'; + $linktitles{'course'}{'listusers'} = 'Show information about users in this course'; + } + } elsif ($linkcontext eq 'community') { + unless ($permission->{'cusr'}) { + $links{'community'}{'singleuser'} = 'View a Community User'; + $linktitles{'community'}{'singleuser'} = 'View information about a user in this community'; + $links{'community'}{'listusers'} = 'List Community Users'; + $linktitles{'community'}{'listusers'} = 'Show information about users in this community'; + } + } + my @menu = ( {categorytitle => 'Single Users', + items => + [ + { + linktext => $links{$linkcontext}{'singleuser'}, + icon => 'edit-redo.png', + #help => 'Course_Change_Privileges', + url => '/adm/createuser?action=singleuser', + permission => ($permission->{'view'} || $permission->{'cusr'}), + linktitle => $linktitles{$linkcontext}{'singleuser'}, + }, + ]}, + + {categorytitle => 'Multiple Users', + items => + [ + { + linktext => $links{$linkcontext}{'upload'}, + icon => 'uplusr.png', + #help => 'Course_Create_Class_List', + url => '/adm/createuser?action=upload', + permission => $permission->{'cusr'}, + linktitle => 'Upload a CSV or a text file containing users.', }, - { text => $links{$context}{'singleuser'}, - help => 'Course_Change_Privileges', - action => 'singleuser', - permission => $permission->{'cusr'}, + { + linktext => $links{$linkcontext}{'listusers'}, + icon => 'mngcu.png', + #help => 'Course_View_Class_List', + url => '/adm/createuser?action=listusers', + permission => ($permission->{'view'} || $permission->{'cusr'}), + linktitle => $linktitles{$linkcontext}{'listusers'}, }, - { text => $links{$context}{'listusers'}, - help => 'Course_View_Class_List', - action => 'listusers', - permission => ($permission->{'view'} || $permission->{'cusr'}), - }, + + ]}, + + {categorytitle => 'Administration', + items => [ ]}, + ); + + if ($context eq 'domain'){ + push(@{ $menu[0]->{items} }, # Single Users + { + linktext => 'User Access Log', + icon => 'document-properties.png', + #help => 'Domain_User_Access_Logs', + url => '/adm/createuser?action=accesslogs', + permission => $permission->{'activity'}, + linktitle => 'View user access log.', + } ); - if ($context eq 'domain' || $context eq 'course') { - my $customlink = { text => 'Edit Custom Roles', - help => 'Course_Editing_Custom_Roles', - action => 'custom', - permission => $permission->{'custom'}, - }; - push(@menu,$customlink); - } - if ($context eq 'course') { + + push(@{ $menu[2]->{items} }, #Category: Administration + { + linktext => 'Custom Roles', + icon => 'emblem-photos.png', + #help => 'Course_Editing_Custom_Roles', + url => '/adm/createuser?action=custom', + permission => $permission->{'custom'}, + linktitle => 'Configure a custom role.', + }, + { + linktext => 'Authoring Space Requests', + icon => 'selfenrl-queue.png', + #help => 'Domain_Role_Approvals', + url => '/adm/createuser?action=processauthorreq', + permission => $permission->{'cusr'}, + linktitle => 'Approve or reject author role requests', + }, + { + linktext => 'LON-CAPA Account Requests', + icon => 'list-add.png', + #help => 'Domain_Username_Approvals', + url => '/adm/createuser?action=processusernamereq', + permission => $permission->{'cusr'}, + linktitle => 'Approve or reject LON-CAPA account requests', + }, + { + linktext => 'Change Log', + icon => 'document-properties.png', + #help => 'Course_User_Logs', + url => '/adm/createuser?action=changelogs', + permission => ($permission->{'cusr'} || $permission->{'view'}), + linktitle => 'View change log.', + }, + ); + + }elsif ($context eq 'course'){ my ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity(); - my @courselinks = - ( - { text => 'Enroll a Single Student', - help => 'Course_Add_Student', - action => 'singlestudent', - permission => $permission->{'cusr'}, - }, - { text => 'Drop Students', - help => 'Course_Drop_Student', - action => 'drop', - permission => $permission->{'cusr'}, - }); - if (!exists($permission->{'cusr_section'})) { - push(@courselinks, - { text => 'Automated Enrollment Manager', - help => 'Course_Automated_Enrollment', - permission => (&Apache::lonnet::auto_run($cnum,$cdom) - && $permission->{'cusr'}), - url => '/adm/populate', - }, - { text => 'Configure User Self-enrollment', - help => 'Course_Self_Enrollment', - action => 'selfenroll', - permission => $permission->{'cusr'}, - }); - } + + my %linktext = ( + 'Course' => { + single => 'Add/Modify a Student', + drop => 'Drop Students', + groups => 'Course Groups', + }, + 'Community' => { + single => 'Add/Modify a Member', + drop => 'Drop Members', + groups => 'Community Groups', + }, + ); + $linktext{'Placement'} = $linktext{'Course'}; + + my %linktitle = ( + 'Course' => { + single => 'Add a user with the role of student to this course', + drop => 'Remove a student from this course.', + groups => 'Manage course groups', + }, + 'Community' => { + single => 'Add a user with the role of member to this community', + drop => 'Remove a member from this community.', + groups => 'Manage community groups', + }, + ); + + $linktitle{'Placement'} = $linktitle{'Course'}; + + push(@{ $menu[0]->{items} }, #Category: Single Users + { + linktext => $linktext{$crstype}{'single'}, + #help => 'Course_Add_Student', + icon => 'list-add.png', + url => '/adm/createuser?action=singlestudent', + permission => $permission->{'cusr'}, + linktitle => $linktitle{$crstype}{'single'}, + }, + ); + + push(@{ $menu[1]->{items} }, #Category: Multiple Users + { + linktext => $linktext{$crstype}{'drop'}, + icon => 'edit-undo.png', + #help => 'Course_Drop_Student', + url => '/adm/createuser?action=drop', + permission => $permission->{'cusr'}, + linktitle => $linktitle{$crstype}{'drop'}, + }, + ); + push(@{ $menu[2]->{items} }, #Category: Administration + { + linktext => 'Helpdesk Access', + icon => 'helpdesk-access.png', + #help => 'Course_Helpdesk_Access', + url => '/adm/createuser?action=helpdesk', + permission => (($permission->{'owner'} || $permission->{'co-owner'}) && + ($permission->{'view'} || $permission->{'cusr'})), + linktitle => 'Helpdesk access options', + }, + { + linktext => 'Custom Roles', + icon => 'emblem-photos.png', + #help => 'Course_Editing_Custom_Roles', + url => '/adm/createuser?action=custom', + permission => $permission->{'custom'}, + linktitle => 'Configure a custom role.', + }, + { + linktext => $linktext{$crstype}{'groups'}, + icon => 'grps.png', + #help => 'Course_Manage_Group', + url => '/adm/coursegroups?refpage=cusr', + permission => $permission->{'grp_manage'}, + linktitle => $linktitle{$crstype}{'groups'}, + }, + { + linktext => 'Change Log', + icon => 'document-properties.png', + #help => 'Course_User_Logs', + url => '/adm/createuser?action=changelogs', + permission => ($permission->{'view'} || $permission->{'cusr'}), + linktitle => 'View change log.', + }, + ); if ($env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_approval'}) { - push(@courselinks, - { text => 'Enrollment Requests', - help => 'Course_Approve_Selfenroll', - action => 'selfenrollqueue', - permission => $permission->{'cusr'}, - }); - } - push(@courselinks, - { text => 'Manage Course Groups', - help => 'Course_Manage_Group', - permission => $permission->{'grp_manage'}, - url => '/adm/coursegroups?refpage=cusr', - }, - { text => 'View Change Logs', - help => 'Course_User_Logs', - action => 'changelogs', - permission => $permission->{'cusr'}, - },); + push(@{ $menu[2]->{items} }, + { + linktext => 'Enrollment Requests', + icon => 'selfenrl-queue.png', + #help => 'Course_Approve_Selfenroll', + url => '/adm/createuser?action=selfenrollqueue', + permission => $permission->{'selfenrolladmin'} || $permission->{'selfenrollview'}, + linktitle =>'Approve or reject enrollment requests.', + }, + ); + } + + if (!exists($permission->{'cusr_section'})){ + if ($crstype ne 'Community') { + push(@{ $menu[2]->{items} }, + { + linktext => 'Automated Enrollment', + icon => 'roles.png', + #help => 'Course_Automated_Enrollment', + permission => (&Apache::lonnet::auto_run($cnum,$cdom) + && (($permission->{'cusr'}) || + ($permission->{'view'}))), + url => '/adm/populate', + linktitle => 'Automated enrollment manager.', + } + ); + } + push(@{ $menu[2]->{items} }, + { + linktext => 'User Self-Enrollment', + icon => 'self_enroll.png', + #help => 'Course_Self_Enrollment', + url => '/adm/createuser?action=selfenroll', + permission => $permission->{'selfenrolladmin'} || $permission->{'selfenrollview'}, + linktitle => 'Configure user self-enrollment.', + }, + ); + } + } elsif ($context eq 'author') { + push(@{ $menu[2]->{items} }, #Category: Administration + { + linktext => 'Change Log', + icon => 'document-properties.png', + #help => 'Course_User_Logs', + url => '/adm/createuser?action=changelogs', + permission => $permission->{'cusr'}, + linktitle => 'View change log.', + }, + { + linktext => 'Co-author Managers', + icon => 'helpdesk-access.png', + #help => 'Coauthor_Management', + url => '/adm/createuser?action=camanagers', + permission => $permission->{'author'}, + linktitle => 'Assign/Revoke right to manage co-author roles', + }, + { + linktext => 'Configure Coauthor Listing', + icon => 'helpdesk-access.png', + #help => 'Coauthor_Settings', + url => '/adm/createuser?action=calist&forceedit=1', + permission => ($permission->{'cusr'}), + linktitle => 'Set availability of coauthor-viewable user listing', + }, + ); + } + push(@{ $menu[2]->{items} }, + { + linktext => 'Role Requests (other domains)', + icon => 'edit-find.png', + #help => 'Role_Requests', + url => '/adm/createuser?action=rolerequests', + permission => $permission->{'cusr'}, + linktitle => 'Role requests for users in other domains', + }, + ); + if (&show_role_requests($context,$env{'request.role.domain'})) { + push(@{ $menu[2]->{items} }, + { + linktext => 'Queued Role Assignments (this domain)', + icon => 'edit-find.png', + #help => 'Role_Approvals', + url => '/adm/createuser?action=queuedroles', + permission => $permission->{'cusr'}, + linktitle => "Role requests for this domain's users", + }, + ); + } + return Apache::lonhtmlcommon::generate_menu(@menu); # { text => 'View Log-in History', # help => 'Course_User_Logins', # action => 'logins', # permission => $permission->{'cusr'}, # }); - push(@menu,@courselinks); - } - my $menu_html = ''; - foreach my $menu_item (@menu) { - next if (! $menu_item->{'permission'}); - $menu_html.='

'; - if (exists($menu_item->{'help'})) { - $menu_html.= - &Apache::loncommon::help_open_topic($menu_item->{'help'}); - } - $menu_html.=''; - if (exists($menu_item->{'url'})) { - $menu_html.=qq{}; - } else { - $menu_html.= - qq{}; } - $menu_html.= &mt($menu_item->{'text'}).''; - $menu_html.='

'; - } - return $menu_html; } sub restore_prev_selections { @@ -3784,10 +6977,11 @@ sub restore_prev_selections { } sub print_selfenroll_menu { - my ($r,$context,$permission) = @_; - my $formname = 'enrollstudent'; + my ($r,$context,$cid,$cdom,$cnum,$currsettings,$additional,$readonly) = @_; + my $crstype = &Apache::loncommon::course_type(); + my $formname = 'selfenroll'; my $nolink = 1; - my ($row,$lt) = &get_selfenroll_titles(); + my ($row,$lt) = &Apache::lonuserutils::get_selfenroll_titles(); my $groupslist = &Apache::lonuserutils::get_groupslist(); my $setsec_js = &Apache::lonuserutils::setsections_javascript($formname,$groupslist); @@ -3796,6 +6990,11 @@ sub print_selfenroll_menu { butn => 'but no user types have been checked.', wilf => "Please uncheck 'activate' or check at least one type.", ); + my $disabled; + if ($readonly) { + $disabled = ' disabled="disabled"'; + } + &js_escape(\%alerts); my $selfenroll_js = <<"ENDSCRIPT"; function update_types(caller,num) { var delidx = getIndexByName('selfenroll_delete'); @@ -3906,7 +7105,7 @@ function validate_types(form) { } } else { if (document.$formname.selfenroll_activate.checked) { - var num = document.enrollstudent.selfenroll_activate.value; + var num = document.$formname.selfenroll_activate.value; countfail = check_types(num,countfail,needaction) } } @@ -3927,12 +7126,13 @@ function validate_types(form) { } function check_types(num,countfail,needaction) { - var typeidx = getIndexByName('selfenroll_types_'+num); + var boxname = 'selfenroll_types_'+num; + var typeidx = getIndexByName(boxname); var count = 0; if (typeidx != -1) { - if (document.$formname.elements[typeidx].length) { - for (var k=0; k'."\n". ''."\n". '

'.$lt->{'selfenroll'}.'

'."\n"; - my ($visible,$cansetvis,$vismsgs,$visactions) = &visible_in_cat($cdom,$cnum); - if (ref($visactions) eq 'HASH') { - if ($visible) { - $output .= '

'.$visactions->{'vis'}.'

'; - } else { - $output .= '

'.$visactions->{'miss'}.'

' - .$visactions->{'yous'}. - '

'.$visactions->{'gen'}.'
'.$visactions->{'coca'}; - if (ref($vismsgs) eq 'ARRAY') { - $output .= '
'.$visactions->{'make'}.'

    '; - foreach my $item (@{$vismsgs}) { - $output .= '
  • '.$visactions->{$item}.'
  • '; + my $visactions = &cat_visibility($cdom); + my ($cathash,%cattype); + my %domconfig = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom); + if (ref($domconfig{'coursecategories'}) eq 'HASH') { + $cathash = $domconfig{'coursecategories'}{'cats'}; + $cattype{'auth'} = $domconfig{'coursecategories'}{'auth'}; + $cattype{'unauth'} = $domconfig{'coursecategories'}{'unauth'}; + if ($cattype{'auth'} eq '') { + $cattype{'auth'} = 'std'; + } + if ($cattype{'unauth'} eq '') { + $cattype{'unauth'} = 'std'; + } + } else { + $cathash = {}; + $cattype{'auth'} = 'std'; + $cattype{'unauth'} = 'std'; + } + if (($cattype{'auth'} eq 'none') && ($cattype{'unauth'} eq 'none')) { + $r->print('
    '.$visactions->{'miss'}.'
    '.$visactions->{'yous'}. + '
    '. + '
    '.$visactions->{'take'}.'
      '. + '
    • '.$visactions->{'dc_chgconf'}.'
    • '. + '
    '); + } elsif (($cattype{'auth'} !~ /^(std|domonly)$/) && ($cattype{'unauth'} !~ /^(std|domonly)$/)) { + if ($currsettings->{'uniquecode'}) { + $r->print(''.$visactions->{'vis'}.''); + } else { + $r->print('
    '.$visactions->{'miss'}.'
    '.$visactions->{'yous'}. + '
    '. + '
    '.$visactions->{'take'}.'
      '. + '
    • '.$visactions->{'dc_setcode'}.'
    • '. + '

    '); + } + } else { + my ($visible,$cansetvis,$vismsgs) = &visible_in_stdcat($cdom,$cnum,\%domconfig); + if (ref($visactions) eq 'HASH') { + if ($visible) { + $output .= '

    '.$visactions->{'vis'}.'

    '; + } else { + $output .= '

    '.$visactions->{'miss'}.'

    ' + .$visactions->{'yous'}. + '

    '.$visactions->{'gen'}.'
    '.$visactions->{'coca'}; + if (ref($vismsgs) eq 'ARRAY') { + $output .= '
    '.$visactions->{'make'}.'

      '; + foreach my $item (@{$vismsgs}) { + $output .= '
    • '.$visactions->{$item}.'
    • '; + } + $output .= '
    '; } - $output .= '
'; + $output .= '

'; } - $output .= '

'; } } - $output .= '
'."\n". + my $actionhref = '/adm/createuser'; + if ($context eq 'domain') { + $actionhref = '/adm/modifycourse'; + } + + my %noedit; + unless ($context eq 'domain') { + %noedit = &get_noedit_fields($cdom,$cnum,$crstype,$row); + } + $output .= ''."\n". &Apache::lonhtmlcommon::start_pick_box(); if (ref($row) eq 'ARRAY') { foreach my $item (@{$row}) { @@ -3995,11 +7260,43 @@ ENDSCRIPT if (ref($lt) eq 'HASH') { $title = $lt->{$item}; } - $output .= - &Apache::lonhtmlcommon::row_title($title, - 'LC_selfenroll_pick_box_title','LC_oddrow_value')."\n"; + $output .= &Apache::lonhtmlcommon::row_title($title); if ($item eq 'types') { - my $curr_types = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_types'}; + my $curr_types; + if (ref($currsettings) eq 'HASH') { + $curr_types = $currsettings->{'selfenroll_types'}; + } + if ($noedit{$item}) { + if ($curr_types eq '*') { + $output .= &mt('Any user in any domain'); + } else { + my @entries = split(/;/,$curr_types); + if (@entries > 0) { + $output .= '
    '; + foreach my $entry (@entries) { + my ($currdom,$typestr) = split(/:/,$entry); + next if ($typestr eq ''); + my $domdesc = &Apache::lonnet::domain($currdom); + my @currinsttypes = split(',',$typestr); + my ($othertitle,$usertypes,$types) = + &Apache::loncommon::sorted_inst_types($currdom); + if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) { + $usertypes->{'any'} = &mt('any user'); + if (keys(%{$usertypes}) > 0) { + $usertypes->{'other'} = &mt('other users'); + } + my @longinsttypes = map { $usertypes->{$_}; } @currinsttypes; + $output .= '
  • '.$domdesc.':'.join(', ',@longinsttypes).'
  • '; + } + } + $output .= '
'; + } else { + $output .= &mt('None'); + } + } + $output .= '
'.&mt('(Set by Domain Coordinator)'); + next; + } my $showdomdesc = 1; my $includeempty = 1; my $num = 0; @@ -4012,13 +7309,13 @@ ENDSCRIPT $output .= ' checked="checked" '; } $output .= 'onchange="javascript:update_types('. - "'selfenroll_all'".');" />'.&mt('Yes').''. + "'selfenroll_all'".');"'.$disabled.' />'.&mt('Yes').''. '  '.&mt('No').''. + "'selfenroll_all'".');"'.$disabled.' />'.&mt('No').''. &Apache::loncommon::end_data_table_row(). &Apache::loncommon::end_data_table(). &mt('Or').'
'. @@ -4040,10 +7337,10 @@ ENDSCRIPT .'
' .''; $output .= '
' + .&selfenroll_inst_types($num,$currdom,\@currinsttypes,$readonly).'' .&Apache::loncommon::end_data_table_row(); $num ++; } @@ -4055,61 +7352,96 @@ ENDSCRIPT } elsif ($curr_types eq '') { $add_domtitle = &mt('Users in other domain:'); } + my ($trusted,$untrusted) = &Apache::lonnet::trusted_domains('enroll',$cdom); $output .= &Apache::loncommon::start_data_table_row() .''.&Apache::loncommon::end_data_table_row() .&Apache::loncommon::end_data_table(); } elsif ($item eq 'registered') { my ($regon,$regoff); - if ($env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_registered'}) { + my $registered; + if (ref($currsettings) eq 'HASH') { + $registered = $currsettings->{'selfenroll_registered'}; + } + if ($noedit{$item}) { + if ($registered) { + $output .= &mt('Must be registered in course'); + } else { + $output .= &mt('No requirement'); + } + $output .= '
'.&mt('(Set by Domain Coordinator)'); + next; + } + if ($registered) { $regon = ' checked="checked" '; - $regoff = ' '; + $regoff = ''; } else { - $regon = ' '; + $regon = ''; $regoff = ' checked="checked" '; } $output .= '  '; } elsif ($item eq 'enroll_dates') { - my $starttime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_start_date'}; - my $endtime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_end_date'}; - if ($starttime eq '') { - $starttime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_start_date'}; - } - if ($endtime eq '') { - $endtime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_end_date'}; + my ($starttime,$endtime); + if (ref($currsettings) eq 'HASH') { + $starttime = $currsettings->{'selfenroll_start_date'}; + $endtime = $currsettings->{'selfenroll_end_date'}; + if ($starttime eq '') { + $starttime = $currsettings->{'default_enrollment_start_date'}; + } + if ($endtime eq '') { + $endtime = $currsettings->{'default_enrollment_end_date'}; + } + } + if ($noedit{$item}) { + $output .= &mt('From: [_1], to: [_2]',&Apache::lonlocal::locallocaltime($starttime), + &Apache::lonlocal::locallocaltime($endtime)); + $output .= '
'.&mt('(Set by Domain Coordinator)'); + next; } my $startform = &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_start_date',$starttime, - undef,undef,undef,undef,undef,undef,undef,$nolink); + $disabled,undef,undef,undef,undef,undef,undef,$nolink); my $endform = &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_end_date',$endtime, - undef,undef,undef,undef,undef,undef,undef,$nolink); + $disabled,undef,undef,undef,undef,undef,undef,$nolink); $output .= &selfenroll_date_forms($startform,$endform); } elsif ($item eq 'access_dates') { - my $starttime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_start_access'}; - my $endtime = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_end_access'}; - if ($starttime eq '') { - $starttime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_start_date'}; - } - if ($endtime eq '') { - $endtime = $env{'course.'.$env{'request.course.id'}.'.default_enrollment_end_date'}; + my ($starttime,$endtime); + if (ref($currsettings) eq 'HASH') { + $starttime = $currsettings->{'selfenroll_start_access'}; + $endtime = $currsettings->{'selfenroll_end_access'}; + if ($starttime eq '') { + $starttime = $currsettings->{'default_enrollment_start_date'}; + } + if ($endtime eq '') { + $endtime = $currsettings->{'default_enrollment_end_date'}; + } + } + if ($noedit{$item}) { + $output .= &mt('From: [_1], to: [_2]',&Apache::lonlocal::locallocaltime($starttime), + &Apache::lonlocal::locallocaltime($endtime)); + $output .= '
'.&mt('(Set by Domain Coordinator)'); + next; } my $startform = &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_start_access',$starttime, - undef,undef,undef,undef,undef,undef,undef,$nolink); + $disabled,undef,undef,undef,undef,undef,undef,$nolink); my $endform = &Apache::lonhtmlcommon::date_setter($formname,'selfenroll_end_access',$endtime, - undef,undef,undef,undef,undef,undef,undef,$nolink); + $disabled,undef,undef,undef,undef,undef,undef,$nolink); $output .= &selfenroll_date_forms($startform,$endform); } elsif ($item eq 'section') { - my $currsec = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_section'}; + my $currsec; + if (ref($currsettings) eq 'HASH') { + $currsec = $currsettings->{'selfenroll_section'}; + } my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum); my $newsecval; if ($currsec ne 'none' && $currsec ne '') { @@ -4117,37 +7449,55 @@ ENDSCRIPT $newsecval = $currsec; } } + if ($noedit{$item}) { + if ($currsec ne '') { + $output .= $currsec; + } else { + $output .= &mt('No specific section'); + } + $output .= '
'.&mt('(Set by Domain Coordinator)'); + next; + } my $sections_select = - &Apache::lonuserutils::course_sections(\%sections_count,'st',$currsec); + &Apache::lonuserutils::course_sections(\%sections_count,'st',$currsec,$disabled); $output .= '
'.$authformcurrent. @@ -1537,13 +2754,38 @@ sub modify_login_block { } sub personal_data_display { - my ($ccuname,$ccdomain,$newuser,$context,$inst_results,$rolesarray) = @_; - my ($output,$showforceid,%userenv,%canmodify,%canmodify_status); + my ($ccuname,$ccdomain,$newuser,$context,$inst_results,$readonly,$rolesarray,$now, + $captchaform,$emailusername,$usertype,$usernameset,$condition,$excluded,$showsubmit) = @_; + my ($output,%userenv,%canmodify,%canmodify_status,$disabled); my @userinfo = ('firstname','middlename','lastname','generation', 'permanentemail','id'); my $rowcount = 0; my $editable = 0; - %canmodify_status = + my %textboxsize = ( + firstname => '15', + middlename => '15', + lastname => '15', + generation => '5', + permanentemail => '25', + id => '15', + ); + + my %lt=&Apache::lonlocal::texthash( + 'pd' => "Personal Data", + 'firstname' => "First Name", + 'middlename' => "Middle Name", + 'lastname' => "Last Name", + 'generation' => "Generation", + 'permanentemail' => "Permanent e-mail address", + 'id' => "Student/Employee ID", + 'lg' => "Login Data", + 'inststatus' => "Affiliation", + 'email' => 'E-mail address', + 'valid' => 'Validation', + 'username' => 'Username', + ); + + %canmodify_status = &Apache::lonuserutils::can_modify_userinfo($context,$ccdomain, ['inststatus'],$rolesarray); if (!$newuser) { @@ -1555,31 +2797,103 @@ sub personal_data_display { &Apache::lonuserutils::can_modify_userinfo($context,$ccdomain, \@userinfo,$rolesarray); } elsif ($context eq 'selfcreate') { - %canmodify = &selfcreate_canmodify($context,$ccdomain,\@userinfo, - $inst_results,$rolesarray); + if ($newuser eq 'email') { + if (ref($emailusername) eq 'HASH') { + if (ref($emailusername->{$usertype}) eq 'HASH') { + my ($infofields,$infotitles) = &Apache::loncommon::emailusername_info(); + @userinfo = (); + if ((ref($infofields) eq 'ARRAY') && (ref($infotitles) eq 'HASH')) { + foreach my $field (@{$infofields}) { + if ($emailusername->{$usertype}->{$field}) { + push(@userinfo,$field); + $canmodify{$field} = 1; + unless ($textboxsize{$field}) { + $textboxsize{$field} = 25; + } + unless ($lt{$field}) { + $lt{$field} = $infotitles->{$field}; + } + if ($emailusername->{$usertype}->{$field} eq 'required') { + $lt{$field} .= '*'; + } + } + } + } + } + } + } else { + %canmodify = &selfcreate_canmodify($context,$ccdomain,\@userinfo, + $inst_results,$rolesarray); + } + } elsif ($readonly) { + $disabled = ' disabled="disabled"'; } - my %lt=&Apache::lonlocal::texthash( - 'pd' => "Personal Data", - 'firstname' => "First Name", - 'middlename' => "Middle Name", - 'lastname' => "Last Name", - 'generation' => "Generation", - 'permanentemail' => "Permanent e-mail address", - 'id' => "Student/Employee ID", - 'lg' => "Login Data", - 'inststatus' => "Affiliation", - ); - my %textboxsize = ( - firstname => '15', - middlename => '15', - lastname => '15', - generation => '5', - permanentemail => '25', - id => '15', - ); + my $genhelp=&Apache::loncommon::help_open_topic('Generation'); $output = '

'.$lt{'pd'}.'

'. &Apache::lonhtmlcommon::start_pick_box(); + if (($context eq 'selfcreate') && ($newuser eq 'email')) { + my $size = 25; + if ($condition) { + if ($condition =~ /^\@[^\@]+$/) { + $size = 10; + } else { + undef($condition); + } + } + if ($excluded) { + unless ($excluded =~ /^\@[^\@]+$/) { + undef($condition); + } + } + $output .= &Apache::lonhtmlcommon::row_title($lt{'email'}.'*',undef, + 'LC_oddrow_value')."\n". + ''; + if ($condition) { + $output .= $condition; + } elsif ($excluded) { + $output .= '
'.&mt('You must use an e-mail address that does not end with [_1]', + $excluded).''; + } + if ($usernameset eq 'first') { + $output .= '
'; + if ($condition) { + $output .= &mt('Your username in LON-CAPA will be the part of your e-mail address before [_1]', + $condition); + } else { + $output .= &mt('Your username in LON-CAPA will be the part of your e-mail address before the @'); + } + $output .= ''; + } + $rowcount ++; + $output .= &Apache::lonhtmlcommon::row_closure(1); + my $upassone = ''; + my $upasstwo = ''; + $output .= &Apache::lonhtmlcommon::row_title(&mt('Password').'*', + 'LC_pick_box_title', + 'LC_oddrow_value')."\n". + $upassone."\n". + &Apache::lonhtmlcommon::row_closure(1)."\n". + &Apache::lonhtmlcommon::row_title(&mt('Confirm password').'*', + 'LC_pick_box_title', + 'LC_oddrow_value')."\n". + $upasstwo. + &Apache::lonhtmlcommon::row_closure()."\n"; + if ($usernameset eq 'free') { + my $onclick = "toggleUsernameDisp(this,'selfcreateusername');"; + $output .= &Apache::lonhtmlcommon::row_title($lt{'username'},undef,'LC_oddrow_value')."\n". + ''.&mt('Use e-mail address: '). + ''.(' 'x2). + ''."\n". + ''."\n".&Apache::lonhtmlcommon::row_closure(1); + $rowcount ++; + } + } foreach my $item (@userinfo) { my $rowtitle = $lt{$item}; my $hiderow = 0; @@ -1593,41 +2907,41 @@ sub personal_data_display { $row .= ''.$inst_results->{$item}; } else { if ($context eq 'selfcreate') { - if ($canmodify{$item}) { - $row .= ''; + if ($canmodify{$item}) { + $row .= ''; $editable ++; } else { $hiderow = 1; } } else { - $row .= ''; + $row .= ''; } } } else { if ($context eq 'selfcreate') { - if (($item eq 'permanentemail') && ($newuser eq 'email')) { - $row .= $ccuname; - } else { - if ($canmodify{$item}) { - $row .= ''; - $editable ++; + if ($canmodify{$item}) { + if ($newuser eq 'email') { + $row .= ''; } else { - $hiderow = 1; + $row .= ''; } + $editable ++; + } else { + $hiderow = 1; } } else { - $row .= ''; + $row .= ''; } } } else { if ($canmodify{$item}) { $row .= ''; + if (($item eq 'id') && (!$newuser)) { + $row .= '
'.&Apache::lonuserutils::forceid_change($context); + } } else { $row .= $userenv{$item}; } - if ($item eq 'id') { - $showforceid = $canmodify{$item}; - } } $row .= &Apache::lonhtmlcommon::row_closure(1); if (!$hiderow) { @@ -1643,13 +2957,26 @@ sub personal_data_display { if ($canmodify_status{'inststatus'}) { $shown = &pick_inst_statuses($userenv{'inststatus'},$usertypes,$types); } else { - $shown .= $userenv{'inststatus'}; if ($userenv{'inststatus'} eq '') { $hiderow = 1; + } else { + my @showitems; + foreach my $item ( map { &unescape($_); } split(':',$userenv{'inststatus'})) { + if (exists($usertypes->{$item})) { + push(@showitems,$usertypes->{$item}); + } else { + push(@showitems,$item); + } + } + if (@showitems) { + $shown = join(', ',@showitems); + } else { + $hiderow = 1; + } } } if (!$hiderow) { - my $row = &Apache::lonhtmlcommon::row_title(&mt('Affliations'),undef,'LC_oddrow_value')."\n". + my $row = &Apache::lonhtmlcommon::row_title(&mt('Affiliations'),undef,'LC_oddrow_value')."\n". $shown.&Apache::lonhtmlcommon::row_closure(1); if ($context eq 'selfcreate') { $rowcount ++; @@ -1659,12 +2986,32 @@ sub personal_data_display { } } } + if (($context eq 'selfcreate') && ($newuser eq 'email')) { + if ($captchaform) { + $output .= &Apache::lonhtmlcommon::row_title($lt{'valid'}.'*', + 'LC_pick_box_title')."\n". + $captchaform."\n".'

'. + &Apache::lonhtmlcommon::row_closure(1); + $rowcount ++; + } + if ($showsubmit) { + my $submit_text = &mt('Create account'); + $output .= &Apache::lonhtmlcommon::row_title()."\n". + '
'; + if ($usertype ne '') { + $output .= ''; + } + $output .= &Apache::lonhtmlcommon::row_closure(1); + } + } $output .= &Apache::lonhtmlcommon::end_pick_box(); if (wantarray) { if ($context eq 'selfcreate') { return($output,$rowcount,$editable); } else { - return ($output,$showforceid); + return $output; } } else { return $output; @@ -1741,7 +3088,7 @@ sub get_inststatuses { # ================================================================= Phase Three sub update_user_data { - my ($r,$context) = @_; + my ($r,$context,$crstype,$brcrum,$showcredits,$permission) = @_; my $uhome=&Apache::lonnet::homeserver($env{'form.ccuname'}, $env{'form.ccdomain'}); # Error messages @@ -1761,38 +3108,48 @@ sub update_user_data { my $newuser = 0; my ($jsback,$elements) = &crumb_utilities(); my $jscript = ''."\n"; - my %breadcrumb_text = &singleuser_breadcrumb(); - my $args; - if ($env{'form.popup'}) { - $args->{'no_nav_bar'} = 1; - } else { - $args = undef; - } - $r->print(&Apache::loncommon::start_page($title,$jscript,$args)); - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage(document.userupdate)", - text=>$breadcrumb_text{'search'}, - faq=>282,bug=>'Instructor Interface',}); + '// '."\n". + ''."\n"; + my %breadcrumb_text = &singleuser_breadcrumb($crstype,$context,$env{'form.ccdomain'}); + push (@{$brcrum}, + {href => "javascript:backPage(document.userupdate)", + text => $breadcrumb_text{'search'}, + faq => 282, + bug => 'Instructor Interface',} + ); if ($env{'form.prevphase'} eq 'userpicked') { - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage(document.userupdate,'get_user_info','select')", - text=>$breadcrumb_text{'userpicked'}, - faq=>282,bug=>'Instructor Interface',}); - } - &Apache::lonhtmlcommon::add_breadcrumb - ({href=>"javascript:backPage(document.userupdate,'$env{'form.prevphase'}','modify')", - text=>$breadcrumb_text{'modify'}, - faq=>282,bug=>'Instructor Interface',}, - {href=>"/adm/createuser", - text=>"Result", - faq=>282,bug=>'Instructor Interface',}); + push(@{$brcrum}, + {href => "javascript:backPage(document.userupdate,'get_user_info','select')", + text => $breadcrumb_text{'userpicked'}, + faq => 282, + bug => 'Instructor Interface',}); + } my $helpitem = 'Course_Change_Privileges'; if ($env{'form.action'} eq 'singlestudent') { $helpitem = 'Course_Add_Student'; + } elsif ($context eq 'author') { + $helpitem = 'Author_Change_Privileges'; + } elsif ($context eq 'domain') { + $helpitem = 'Domain_Change_Privileges'; + } + push(@{$brcrum}, + {href => "javascript:backPage(document.userupdate,'$env{'form.prevphase'}','modify')", + text => $breadcrumb_text{'modify'}, + faq => 282, + bug => 'Instructor Interface',}, + {href => "/adm/createuser", + text => "Result", + faq => 282, + bug => 'Instructor Interface', + help => $helpitem}); + my $args = {bread_crumbs => $brcrum, + bread_crumbs_component => 'User Management'}; + if ($env{'form.popup'}) { + $args->{'no_nav_bar'} = 1; } - $r->print(&Apache::lonhtmlcommon::breadcrumbs('User Management', - $helpitem)); + $r->print(&Apache::loncommon::start_page($title,$jscript,$args)); $r->print(&update_result_form($uhome)); # Check Inputs if (! $env{'form.ccuname'} ) { @@ -1823,9 +3180,12 @@ sub update_user_data { if (! exists($env{'form.makeuser'})) { # Modifying an existing user, so check the validity of the name if ($uhome eq 'no_host') { - $r->print($error.&mt('Unable to determine home server for '). - $env{'form.ccuname'}.&mt(' in domain '). - $env{'form.ccdomain'}.'.'); + $r->print( + $error + .'

' + .&mt('Unable to determine home server for [_1] in domain [_2].', + '"'.$env{'form.ccuname'}.'"','"'.$env{'form.ccdomain'}.'"') + .'

'); return; } } @@ -1846,6 +3206,9 @@ sub update_user_data { $amode='localauth'; $genpwd=$env{'form.locarg'}; $genpwd=" " if (!$genpwd); + } elsif ($env{'form.login'} eq 'lti') { + $amode='lti'; + $genpwd=" "; } elsif (($env{'form.login'} eq 'nochange') || ($env{'form.login'} eq '' )) { # There is no need to tell the user we did not change what they @@ -1853,17 +3216,26 @@ sub update_user_data { # If they are creating a new user but have not specified login # information this will be caught below. } else { - $r->print($error.&mt('Invalid login mode or password').$end.$rtnlink); - return; + $r->print($error.&mt('Invalid login mode or password').$end.$rtnlink); + return; } $r->print('

'.&mt('User [_1] in domain [_2]', - $env{'form.ccuname'}, $env{'form.ccdomain'}).'

'); + $env{'form.ccuname'}.' ('.&Apache::loncommon::plainname($env{'form.ccuname'}, + $env{'form.ccdomain'}).')', $env{'form.ccdomain'}).''); + my %prog_state = &Apache::lonhtmlcommon::Create_PrgWin($r,2); + my (%alerts,%rulematch,%inst_results,%curr_rules); - my @usertools = ('aboutme','blog','portfolio'); - my @requestcourses = ('official','unofficial'); + my @userinfo = ('firstname','middlename','lastname','generation','permanentemail','id'); + my @usertools = ('aboutme','blog','portfolio','portaccess','timezone'); + my @requestcourses = ('official','unofficial','community','textbook','placement','lti'); + my @requestauthor = ('requestauthor'); + my @authordefaults = ('webdav','editors'); my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($env{'form.ccdomain'}); + my %canmodify_status = + &Apache::lonuserutils::can_modify_userinfo($context,$env{'form.ccdomain'}, + ['inststatus']); if ($env{'form.makeuser'}) { $r->print('

'.&mt('Creating new account.').'

'); # Check for the authentication mode and password @@ -1913,6 +3285,7 @@ sub update_user_data { } } } + &Apache::lonhtmlcommon::Increment_PrgWin($r, \%prog_state); # Call modifyuser my $result = &Apache::lonnet::modifyuser ($env{'form.ccdomain'},$env{'form.ccuname'},$env{'form.cid'}, @@ -1923,49 +3296,92 @@ sub update_user_data { $r->print(&mt('Generating user').': '.$result); $uhome = &Apache::lonnet::homeserver($env{'form.ccuname'}, $env{'form.ccdomain'}); - my (%changeHash,%newcustom,%changed); + my (%changeHash,%newcustom,%changed,%changedinfo); if ($uhome ne 'no_host') { - if ($env{'form.customquota'} == 1) { - if ($env{'form.portfolioquota'} eq '') { - $newcustom{'quota'} = 0; - } else { - $newcustom{'quota'} = $env{'form.portfolioquota'}; - $newcustom{'quota'} =~ s/[^\d\.]//g; - } - $changed{'quota'} = "a_admin($newcustom{'quota'},\%changeHash); - } - foreach my $item (@usertools) { - if ($env{'form.custom'.$item} == 1) { - $newcustom{$item} = $env{'form.tools_'.$item}; - $changed{$item} = &tool_admin($item,$newcustom{$item}, - \%changeHash,'tools'); - } - } - foreach my $item (@requestcourses) { - $newcustom{$item} = $env{'form.requestcourses_'.$item}; - $changed{$item} = &tool_admin($item,$newcustom{$item}, - \%changeHash,'requestcourses'); - } - if (exists($env{'form.inststatus'})) { - my @inststatuses = &Apache::loncommon::get_env_multiple('form.inststatus'); - if (@inststatuses > 0) { - $changeHash{'inststatus'} = join(',',@inststatuses); - $changed{'inststatus'} = $changeHash{'inststatus'}; + if ($context eq 'domain') { + foreach my $name ('portfolio','author') { + if ($env{'form.custom_'.$name.'quota'} == 1) { + if ($env{'form.'.$name.'quota'} eq '') { + $newcustom{$name.'quota'} = 0; + } else { + $newcustom{$name.'quota'} = $env{'form.'.$name.'quota'}; + $newcustom{$name.'quota'} =~ s/[^\d\.]//g; + } + if ("a_admin($newcustom{$name.'quota'},\%changeHash,$name)) { + $changed{$name.'quota'} = 1; + } + } + } + foreach my $item (@usertools) { + if ($env{'form.custom'.$item} == 1) { + $newcustom{$item} = $env{'form.tools_'.$item}; + $changed{$item} = &tool_admin($item,$newcustom{$item}, + \%changeHash,'tools'); + } + } + foreach my $item (@requestcourses) { + if ($env{'form.custom'.$item} == 1) { + $newcustom{$item} = $env{'form.crsreq_'.$item}; + if ($env{'form.crsreq_'.$item} eq 'autolimit') { + $newcustom{$item} .= '='; + $env{'form.crsreq_'.$item.'_limit'} =~ s/\D+//g; + if ($env{'form.crsreq_'.$item.'_limit'}) { + $newcustom{$item} .= $env{'form.crsreq_'.$item.'_limit'}; + } + } + $changed{$item} = &tool_admin($item,$newcustom{$item}, + \%changeHash,'requestcourses'); + } + } + if ($env{'form.customrequestauthor'} == 1) { + $newcustom{'requestauthor'} = $env{'form.requestauthor'}; + $changed{'requestauthor'} = &tool_admin('requestauthor', + $newcustom{'requestauthor'}, + \%changeHash,'requestauthor'); + } + if ($env{'form.customeditors'} == 1) { + my @editors; + my @posseditors = &Apache::loncommon::get_env_multiple('form.custom_editor'); + if (@posseditors) { + foreach my $editor (@posseditors) { + if (grep(/^\Q$editor\E$/,@posseditors)) { + unless (grep(/^\Q$editor\E$/,@editors)) { + push(@editors,$editor); + } + } + } + } + if (@editors) { + @editors = sort(@editors); + $changed{'editors'} = &tool_admin('editors',join(',',@editors), + \%changeHash,'authordefaults'); + } + } + if ($env{'form.customwebdav'} == 1) { + $newcustom{'webdav'} = $env{'form.authordefaults_webdav'}; + $changed{'webdav'} = &tool_admin('webdav',$newcustom{'webdav'}, + \%changeHash,'authordefaults'); + } + } + if ($canmodify_status{'inststatus'}) { + if (exists($env{'form.inststatus'})) { + my @inststatuses = &Apache::loncommon::get_env_multiple('form.inststatus'); + if (@inststatuses > 0) { + $changeHash{'inststatus'} = join(',',@inststatuses); + $changed{'inststatus'} = $changeHash{'inststatus'}; + } } } if (keys(%changed)) { - $changeHash{'firstname'} = $env{'form.cfirstname'}; - $changeHash{'middlename'} = $env{'form.cmiddlename'}; - $changeHash{'lastname'} = $env{'form.clastname'}; - $changeHash{'generation'} = $env{'form.cgeneration'}; - $changeHash{'id'} = $env{'form.cid'}; - $changeHash{'permanentemail'} = $env{'form.cpermanentemail'}; + foreach my $item (@userinfo) { + $changeHash{$item} = $env{'form.c'.$item}; + } my $chgresult = &Apache::lonnet::put('environment',\%changeHash, $env{'form.ccdomain'},$env{'form.ccuname'}); - } + } } - $r->print('
'.&mt('Home server').': '.$uhome.' '. + $r->print('
'.&mt('Home Server').': '.$uhome.' '. &Apache::lonnet::hostname($uhome)); } elsif (($env{'form.login'} ne 'nochange') && ($env{'form.login'} ne '' )) { @@ -1974,36 +3390,62 @@ sub update_user_data { $r->print($error.'Invalid login mode or password'.$end.$rtnlink); return; } - # Only allow authentification modification if the person has authority + # Only allow authentication modification if the person has authority if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'})) { $r->print('Modifying authentication: '. &Apache::lonnet::modifyuserauth( $env{'form.ccdomain'},$env{'form.ccuname'}, $amode,$genpwd)); - $r->print('
'.&mt('Home server').': '.&Apache::lonnet::homeserver + $r->print('
'.&mt('Home Server').': '.&Apache::lonnet::homeserver ($env{'form.ccuname'},$env{'form.ccdomain'})); } else { # Okay, this is a non-fatal error. - $r->print($error.&mt('You do not have the authority to modify this users authentification information').'.'.$end); + $r->print($error.&mt('You do not have privileges to modify the authentication configuration for this user.').$end); } + } elsif (($env{'form.intarg'} ne '') && + (&Apache::lonnet::queryauthenticate($env{'form.ccuname'},$env{'form.ccdomain'}) =~ /^internal:/) && + (&Apache::lonuserutils::can_change_internalpass($env{'form.ccuname'},$env{'form.ccdomain'},$crstype,$permission))) { + $r->print('Modifying authentication: '. + &Apache::lonnet::modifyuserauth( + $env{'form.ccdomain'},$env{'form.ccuname'}, + 'internal',$env{'form.intarg'})); } + $r->rflush(); # Finish display of header before time consuming actions start + &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state); ## - my (@userroles,%userupdate,$cnum,$cdom,$namechanged); + my (@userroles,%userupdate,$cnum,$cdom,$defaultcredits,%namechanged); if ($context eq 'course') { - ($cnum,$cdom) = &Apache::lonuserutils::get_course_identity(); + ($cnum,$cdom) = + &Apache::lonuserutils::get_course_identity(); + $crstype = &Apache::loncommon::course_type($cdom.'_'.$cnum); + if ($showcredits) { + $defaultcredits = &Apache::lonuserutils::get_defaultcredits($cdom,$cnum); + } } if (! $env{'form.makeuser'} ) { # Check for need to change my %userenv = &Apache::lonnet::get ('environment',['firstname','middlename','lastname','generation', - 'id','permanentemail','portfolioquota','inststatus','tools.aboutme', - 'tools.blog','tools.portfolio','requestcourses.official', - 'requestcourses.unofficial'], + 'id','permanentemail','portfolioquota','authorquota','inststatus', + 'tools.aboutme','tools.blog','tools.webdav', + 'tools.portfolio','tools.timezone','tools.portaccess', + 'authormanagers','authoreditors','requestauthor', + 'requestcourses.official','requestcourses.unofficial', + 'requestcourses.community','requestcourses.textbook', + 'requestcourses.placement','requestcourses.lti', + 'reqcrsotherdom.official','reqcrsotherdom.unofficial', + 'reqcrsotherdom.community','reqcrsotherdom.textbook', + 'reqcrsotherdom.placement','domcoord.author'], $env{'form.ccdomain'},$env{'form.ccuname'}); my ($tmp) = keys(%userenv); if ($tmp =~ /^(con_lost|error)/i) { %userenv = (); } + unless (($userenv{'domcoord.author'} eq 'blocked') && + (($env{'user.name'} ne $env{'form.ccuname'}) || + ($env{'user.domain'} ne $env{'form.ccdomain'}))) { + push(@authordefaults,'managers'); + } my $no_forceid_alert; # Check to see if user information can be changed my %domconfig = @@ -2028,7 +3470,7 @@ sub update_user_data { } } elsif ($context eq 'author') { if ($rolenum eq $auname && $roledom eq $audom) { - if (!grep(/^\Q$role\E$/,@userroles)) { + if (!grep(/^\Q$role\E$/,@userroles)) { push(@userroles,$role); } } @@ -2072,10 +3514,9 @@ sub update_user_data { if ($role eq 'cr') { push(@longroles,'Custom'); } else { - push(@longroles,&Apache::lonnet::plaintext($role)); + push(@longroles,&Apache::lonnet::plaintext($role,$crstype)); } } - my @userinfo = ('firstname','middlename','lastname','generation','permanentemail','id'); my %canmodify = &Apache::lonuserutils::can_modify_userinfo($context,$env{'form.ccdomain'},\@userinfo,\@userroles); foreach my $item (@userinfo) { # Strip leading and trailing whitespace @@ -2121,39 +3562,55 @@ sub update_user_data { } } } - my ($quotachanged,$oldportfolioquota,$newportfolioquota,$oldinststatus, - $inststatus,$newinststatus,$oldisdefault,$newisdefault,$olddefquotatext, - $newdefquotatext,%oldaccess,%oldaccesstext,%newaccess,%newaccesstext, - $oldinststatuses,$newinststatuses); - my ($defquota,$settingstatus) = - &Apache::loncommon::default_quota($env{'form.ccdomain'},$inststatus); - my ($showquota,$showtools,$showrequestcourses,$showinststatus); + my (%quotachanged,%oldquota,%newquota,%olddefquota,%newdefquota, + $oldinststatus,$newinststatus,%oldisdefault,%newisdefault,%oldsettings, + %oldsettingstext,%newsettings,%newsettingstext,@disporder, + %oldsettingstatus,%newsettingstatus); + @disporder = ('inststatus'); + if ($env{'request.role.domain'} eq $env{'form.ccdomain'}) { + push(@disporder,('requestcourses','requestauthor','authordefaults')); + } else { + push(@disporder,'reqcrsotherdom'); + } + push(@disporder,('quota','tools')); + $oldinststatus = $userenv{'inststatus'}; + foreach my $name ('portfolio','author') { + ($olddefquota{$name},$oldsettingstatus{$name}) = + &Apache::loncommon::default_quota($env{'form.ccdomain'},$oldinststatus,$name); + ($newdefquota{$name},$newsettingstatus{$name}) = ($olddefquota{$name},$oldsettingstatus{$name}); + } + my %canshow; if (&Apache::lonnet::allowed('mpq',$env{'form.ccdomain'})) { - $showquota = 1; + $canshow{'quota'} = 1; } if (&Apache::lonnet::allowed('mut',$env{'form.ccdomain'})) { - $showtools = 1; + $canshow{'tools'} = 1; } if (&Apache::lonnet::allowed('ccc',$env{'form.ccdomain'})) { - $showrequestcourses = 1; + $canshow{'requestcourses'} = 1; + } elsif (&Apache::lonnet::allowed('ccc',$env{'request.role.domain'})) { + $canshow{'reqcrsotherdom'} = 1; } if (&Apache::lonnet::allowed('mau',$env{'form.ccdomain'})) { - $showinststatus = 1; + $canshow{'inststatus'} = 1; + } + if (&Apache::lonnet::allowed('cau',$env{'form.ccdomain'})) { + $canshow{'requestauthor'} = 1; + $canshow{'authordefaults'} = 1; } my (%changeHash,%changed); - $oldinststatus = $userenv{'inststatus'}; if ($oldinststatus eq '') { - $oldinststatuses = $othertitle; + $oldsettings{'inststatus'} = $othertitle; } else { if (ref($usertypes) eq 'HASH') { - $oldinststatuses = join(', ',map{ $usertypes->{ &unescape($_) }; } (split(/:/,$userenv{'inststatus'}))); + $oldsettings{'inststatus'} = join(', ',map{ $usertypes->{ &unescape($_) }; } (split(/:/,$userenv{'inststatus'}))); } else { - $oldinststatuses = join(', ',map{ &unescape($_); } (split(/:/,$userenv{'inststatus'}))); + $oldsettings{'inststatus'} = join(', ',map{ &unescape($_); } (split(/:/,$userenv{'inststatus'}))); } } $changeHash{'inststatus'} = $userenv{'inststatus'}; - my %canmodify_inststatus = &Apache::lonuserutils::can_modify_userinfo($context,$env{'form.ccdomain'},['inststatus'],\@userroles); - if ($canmodify_inststatus{'inststatus'}) { + if ($canmodify_status{'inststatus'}) { + $canshow{'inststatus'} = 1; if (exists($env{'form.inststatus'})) { my @inststatuses = &Apache::loncommon::get_env_multiple('form.inststatus'); if (@inststatuses > 0) { @@ -2161,102 +3618,203 @@ sub update_user_data { $changeHash{'inststatus'} = $newinststatus; if ($newinststatus ne $oldinststatus) { $changed{'inststatus'} = $newinststatus; + foreach my $name ('portfolio','author') { + ($newdefquota{$name},$newsettingstatus{$name}) = + &Apache::loncommon::default_quota($env{'form.ccdomain'},$newinststatus,$name); + } } if (ref($usertypes) eq 'HASH') { - $newinststatuses = join(', ',map{ $usertypes->{$_}; } (@inststatuses)); + $newsettings{'inststatus'} = join(', ',map{ $usertypes->{$_}; } (@inststatuses)); } else { - $newinststatuses = join(', ',map{ $usertypes->{$_}; } (@inststatuses)); + $newsettings{'inststatus'} = join(', ',@inststatuses); + } + } + } else { + $newinststatus = ''; + $changeHash{'inststatus'} = $newinststatus; + $newsettings{'inststatus'} = $othertitle; + if ($newinststatus ne $oldinststatus) { + $changed{'inststatus'} = $changeHash{'inststatus'}; + foreach my $name ('portfolio','author') { + ($newdefquota{$name},$newsettingstatus{$name}) = + &Apache::loncommon::default_quota($env{'form.ccdomain'},$newinststatus,$name); + } + } + } + } elsif ($context ne 'selfcreate') { + $canshow{'inststatus'} = 1; + $newsettings{'inststatus'} = $oldsettings{'inststatus'}; + } + foreach my $name ('portfolio','author') { + $changeHash{$name.'quota'} = $userenv{$name.'quota'}; + } + if ($context eq 'domain') { + foreach my $name ('portfolio','author') { + if ($userenv{$name.'quota'} ne '') { + $oldquota{$name} = $userenv{$name.'quota'}; + if ($env{'form.custom_'.$name.'quota'} == 1) { + if ($env{'form.'.$name.'quota'} eq '') { + $newquota{$name} = 0; + } else { + $newquota{$name} = $env{'form.'.$name.'quota'}; + $newquota{$name} =~ s/[^\d\.]//g; + } + if ($newquota{$name} != $oldquota{$name}) { + if ("a_admin($newquota{$name},\%changeHash,$name)) { + $changed{$name.'quota'} = 1; + } + } + } else { + if ("a_admin('',\%changeHash,$name)) { + $changed{$name.'quota'} = 1; + $newquota{$name} = $newdefquota{$name}; + $newisdefault{$name} = 1; + } } } else { - $newinststatus = ''; - $changeHash{'inststatus'} = $newinststatus; - $newinststatuses = $othertitle; - if ($newinststatus ne $oldinststatus) { - $changed{'inststatus'} = $changeHash{'inststatus'}; + $oldisdefault{$name} = 1; + $oldquota{$name} = $olddefquota{$name}; + if ($env{'form.custom_'.$name.'quota'} == 1) { + if ($env{'form.'.$name.'quota'} eq '') { + $newquota{$name} = 0; + } else { + $newquota{$name} = $env{'form.'.$name.'quota'}; + $newquota{$name} =~ s/[^\d\.]//g; + } + if ("a_admin($newquota{$name},\%changeHash,$name)) { + $changed{$name.'quota'} = 1; + } + } else { + $newquota{$name} = $newdefquota{$name}; + $newisdefault{$name} = 1; } } + if ($oldisdefault{$name}) { + $oldsettingstext{'quota'}{$name} = &get_defaultquota_text($oldsettingstatus{$name}); + } else { + $oldsettingstext{'quota'}{$name} = &mt('custom quota: [_1] MB',$oldquota{$name}); + } + if ($newisdefault{$name}) { + $newsettingstext{'quota'}{$name} = &get_defaultquota_text($newsettingstatus{$name}); + } else { + $newsettingstext{'quota'}{$name} = &mt('custom quota: [_1] MB',$newquota{$name}); + } + } + &tool_changes('tools',\@usertools,\%oldsettings,\%oldsettingstext,\%userenv, + \%changeHash,\%changed,\%newsettings,\%newsettingstext); + if ($env{'form.ccdomain'} eq $env{'request.role.domain'}) { + &tool_changes('requestcourses',\@requestcourses,\%oldsettings,\%oldsettingstext, + \%userenv,\%changeHash,\%changed,\%newsettings,\%newsettingstext); + my ($isadv,$isauthor) = + &Apache::lonnet::is_advanced_user($env{'form.ccdomain'},$env{'form.ccuname'}); + unless ($isauthor) { + &tool_changes('requestauthor',\@requestauthor,\%oldsettings,\%oldsettingstext, + \%userenv,\%changeHash,\%changed,\%newsettings,\%newsettingstext); + } + &tool_changes('authordefaults',\@authordefaults,\%oldsettings,\%oldsettingstext, + \%userenv,\%changeHash,\%changed,\%newsettings,\%newsettingstext); + } else { + &tool_changes('reqcrsotherdom',\@requestcourses,\%oldsettings,\%oldsettingstext, + \%userenv,\%changeHash,\%changed,\%newsettings,\%newsettingstext); + } + } + foreach my $item (@userinfo) { + if ($env{'form.c'.$item} ne $userenv{$item}) { + $namechanged{$item} = 1; } } - $changeHash{'portfolioquota'} = $userenv{'portfolioquota'}; - if ($userenv{'portfolioquota'} ne '') { - $oldportfolioquota = $userenv{'portfolioquota'}; - if ($env{'form.customquota'} == 1) { - if ($env{'form.portfolioquota'} eq '') { - $newportfolioquota = 0; - } else { - $newportfolioquota = $env{'form.portfolioquota'}; - $newportfolioquota =~ s/[^\d\.]//g; - } - if ($newportfolioquota != $oldportfolioquota) { - $changed{'quota'} = "a_admin($newportfolioquota,\%changeHash); - } - } else { - $changed{'quota'} = "a_admin('',\%changeHash); - $newportfolioquota = $defquota; - $newisdefault = 1; - } - } else { - $oldisdefault = 1; - $oldportfolioquota = $defquota; - if ($env{'form.customquota'} == 1) { - if ($env{'form.portfolioquota'} eq '') { - $newportfolioquota = 0; - } else { - $newportfolioquota = $env{'form.portfolioquota'}; - $newportfolioquota =~ s/[^\d\.]//g; - } - $changed{'quota'} = "a_admin($newportfolioquota,\%changeHash); - } else { - $newportfolioquota = $defquota; - $newisdefault = 1; - } - } - if ($oldisdefault) { - $olddefquotatext = &get_defaultquota_text($settingstatus); - } - if ($newisdefault) { - $newdefquotatext = &get_defaultquota_text($settingstatus); - } - &tool_changes('tools',\@usertools,\%oldaccess,\%oldaccesstext,\%userenv, - \%changeHash,\%changed,\%newaccess,\%newaccesstext); - &tool_changes('requestcourses',\@requestcourses,\%oldaccess,\%oldaccesstext, - \%userenv, \%changeHash,\%changed,\%newaccess,\%newaccesstext); - if ($env{'form.cfirstname'} ne $userenv{'firstname'} || - $env{'form.cmiddlename'} ne $userenv{'middlename'} || - $env{'form.clastname'} ne $userenv{'lastname'} || - $env{'form.cgeneration'} ne $userenv{'generation'} || - $env{'form.cid'} ne $userenv{'id'} || - $env{'form.cpermanentemail'} ne $userenv{'permanentemail'} ) { - $namechanged = 1; - } - if (($namechanged) || (keys(%changed) > 0)) { - $changeHash{'firstname'} = $env{'form.cfirstname'}; - $changeHash{'middlename'} = $env{'form.cmiddlename'}; - $changeHash{'lastname'} = $env{'form.clastname'}; - $changeHash{'generation'} = $env{'form.cgeneration'}; - $changeHash{'id'} = $env{'form.cid'}; - $changeHash{'permanentemail'} = $env{'form.cpermanentemail'}; + foreach my $name ('portfolio','author') { + $oldsettings{'quota'}{$name} = &mt('[_1] MB',$oldquota{$name}); + $newsettings{'quota'}{$name} = &mt('[_1] MB',$newquota{$name}); + } + if ((keys(%namechanged) > 0) || (keys(%changed) > 0)) { my ($chgresult,$namechgresult); if (keys(%changed) > 0) { - $chgresult = + $chgresult = &Apache::lonnet::put('environment',\%changeHash, $env{'form.ccdomain'},$env{'form.ccuname'}); if ($chgresult eq 'ok') { + my ($ca_mgr_del,%ca_mgr_add); + if ($changed{'managers'}) { + my (@adds,@dels); + if ($changeHash{'authormanagers'} eq '') { + @dels = split(/,/,$userenv{'authormanagers'}); + } elsif ($userenv{'authormanagers'} eq '') { + @adds = split(/,/,$changeHash{'authormanagers'}); + } else { + my @old = split(/,/,$userenv{'authormanagers'}); + my @new = split(/,/,$changeHash{'authormanagers'}); + my @diffs = &Apache::loncommon::compare_arrays(\@old,\@new); + if (@diffs) { + foreach my $user (@diffs) { + if (grep(/^\Q$user\E$/,@old)) { + push(@dels,$user); + } elsif (grep(/^\Q$user\E$/,@new)) { + push(@adds,$user); + } + } + } + } + my $key = "internal.manager./$env{'form.ccdomain'}/$env{'form.ccuname'}"; + if (@dels) { + foreach my $user (@dels) { + if ($user =~ /^($match_username):($match_domain)$/) { + &Apache::lonnet::del('environment',[$key],$2,$1); + } + } + my $curruser = $env{'user.name'}.':'.$env{'user.domain'}; + if (grep(/^\Q$curruser\E$/,@dels)) { + $ca_mgr_del = $key; + } + } + if (@adds) { + foreach my $user (@adds) { + if ($user =~ /^($match_username):($match_domain)$/) { + &Apache::lonnet::put('environment',{$key => 1},$2,$1); + } + } + my $curruser = $env{'user.name'}.':'.$env{'user.domain'}; + if (grep(/^\Q$curruser\E$/,@adds)) { + $ca_mgr_add{$key} = 1; + } + } + } if (($env{'user.name'} eq $env{'form.ccuname'}) && ($env{'user.domain'} eq $env{'form.ccdomain'})) { my %newenvhash; foreach my $key (keys(%changed)) { - if (($key eq 'official') || ($key eq 'unofficial')) { + if (($key eq 'official') || ($key eq 'unofficial') || + ($key eq 'community') || ($key eq 'textbook') || + ($key eq 'placement') || ($key eq 'lti')) { $newenvhash{'environment.requestcourses.'.$key} = $changeHash{'requestcourses.'.$key}; - if ($changeHash{'requestcourses.'.$key} ne '') { - $newenvhash{'environment.canrequest.'.$key} = - $changeHash{'requestcourses.'.$key}; + if ($changeHash{'requestcourses.'.$key}) { + $newenvhash{'environment.canrequest.'.$key} = 1; } else { $newenvhash{'environment.canrequest.'.$key} = &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'}, $key,'reload','requestcourses'); } + } elsif ($key eq 'requestauthor') { + $newenvhash{'environment.'.$key} = $changeHash{$key}; + if ($changeHash{$key}) { + $newenvhash{'environment.canrequest.author'} = 1; + } else { + $newenvhash{'environment.canrequest.author'} = + &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'}, + $key,'reload','requestauthor'); + } + } elsif ($key eq 'editors') { + $newenvhash{'environment.author'.$key} = $changeHash{'author'.$key}; + if ($key eq 'editors') { + if ($env{'form.customeditors'}) { + $newenvhash{'environment.editors'} = $changeHash{'author'.$key}; + } else { + $newenvhash{'environment.editors'} = + &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'}, + $key,'reload','authordefaults'); + } + } } elsif ($key ne 'quota') { $newenvhash{'environment.tools.'.$key} = $changeHash{'tools.'.$key}; @@ -2265,24 +3823,39 @@ sub update_user_data { $changeHash{'tools.'.$key}; } else { $newenvhash{'environment.availabletools.'.$key} = - &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'}, $key,'reload','tools'); + &Apache::lonnet::usertools_access($env{'user.name'},$env{'user.domain'}, + $key,'reload','tools'); } } } if (keys(%newenvhash)) { &Apache::lonnet::appenv(\%newenvhash); } + } else { + if ($ca_mgr_del) { + &Apache::lonnet::delenv($ca_mgr_del); + } + if (keys(%ca_mgr_add)) { + &Apache::lonnet::appenv(\%ca_mgr_add); + } + } + if ($changed{'aboutme'}) { + &Apache::loncommon::devalidate_aboutme_cache($env{'form.ccuname'}, + $env{'form.ccdomain'}); } } } - if ($namechanged) { - # Make the change + if (keys(%namechanged) > 0) { + foreach my $field (@userinfo) { + $changeHash{$field} = $env{'form.c'.$field}; + } +# Make the change $namechgresult = &Apache::lonnet::modifyuser($env{'form.ccdomain'}, $env{'form.ccuname'},$changeHash{'id'},undef,undef, $changeHash{'firstname'},$changeHash{'middlename'}, $changeHash{'lastname'},$changeHash{'generation'}, - $changeHash{'id'},undef,$changeHash{'permanentemail'}); + $changeHash{'id'},undef,$changeHash{'permanentemail'},undef,\@userinfo); %userupdate = ( lastname => $env{'form.clastname'}, middlename => $env{'form.cmiddlename'}, @@ -2291,126 +3864,16 @@ sub update_user_data { id => $env{'form.cid'}, ); } - if (($namechanged && $namechgresult eq 'ok') || + if (((keys(%namechanged) > 0) && $namechgresult eq 'ok') || ((keys(%changed) > 0) && $chgresult eq 'ok')) { # Tell the user we changed the name - my %lt=&Apache::lonlocal::texthash( - 'uic' => 'User Information Changed', - 'frst' => 'First Name', - 'mddl' => 'Middle Name', - 'lst' => 'Last Name', - 'gen' => 'Generation', - 'id' => 'Student/Employee ID', - 'mail' => 'Permanent e-mail address', - 'disk' => 'Disk space allocated to portfolio files', - 'blog' => 'Blog Availability', - 'aboutme' => 'Personal Information Page Availability', - 'portfolio' => 'Portfolio Availability', - 'official' => 'Can Request Official Courses', - 'unofficial' => 'Can Request Unofficial Courses', - 'inststatus' => "Affiliation", - 'prvs' => 'Previous Value:', - 'chto' => 'Changed To:' - ); - $r->print('

'.$lt{'uic'}.'

'. - &Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_header_row()); - $r->print(<<"END"); -
 $lt{'frst'}$lt{'mddl'}$lt{'lst'}$lt{'gen'}$lt{'id'}$lt{'mail'}$lt{'inststatus'}$lt{$item}$lt{'disk'}$lt{$item}$lt{'prvs'}$userenv{'firstname'} $userenv{'middlename'} $userenv{'lastname'} $userenv{'generation'} $userenv{'id'}$userenv{'permanentemail'} $oldinststatuses$oldaccess{$item} $oldaccesstext{$item}$oldportfolioquota Mb $olddefquotatext $oldaccess{$item} $oldaccesstext{$item} $lt{'chto'}$env{'form.cfirstname'} $env{'form.cmiddlename'} $env{'form.clastname'} $env{'form.cgeneration'} $env{'form.cid'} $env{'form.cpermanentemail'} $newinststatuses$newaccess{$item} $newaccesstext{$item} $newportfolioquota Mb $newdefquotatext $newaccess{$item} $newaccesstext{$item}  '.$lt{'prvs'}.''.$lt{'chto'}.'$lt{$item}".$userenv->{$item}."$value $lt{$item}\n"); + unless ($item eq 'managers') { + $r->print($oldsetting->{$item}); + } + if ($oldsettingtext->{$item}) { + if ($oldsetting->{$item}) { + unless ($item eq 'managers') { + $r->print(' -- '); + } + } + $r->print($oldsettingtext->{$item}); + } + $r->print(""); + unless ($item eq 'managers') { + $r->print($newsetting->{$item}); + } + if ($newsettingtext->{$item}) { + if ($newsetting->{$item}) { + unless ($item eq 'managers') { + $r->print(' -- '); + } + } + $r->print($newsettingtext->{$item}); + } + $r->print("$lt{$item}".$oldsetting->{$item}.' '.$oldsettingtext->{$item}."".$newsetting->{$item}.' '.$newsettingtext->{$item}."$lt{$name.$entry}".$oldsettingtext->{$entry}->{$name}."".$newsettingtext->{$entry}->{$name}."$lt{$entry}".$oldsetting->{$entry}.' '.$oldsettingtext->{$entry}."".$newsetting->{$entry}.' '.$newsettingtext->{$entry}."
'.$lt{'prv'}.''.$lt{'crl'}.''.$lt{'dml'}. -''.$lt{'ssl'}.''.$privtext.''. - ($courselevel{$priv}?'':' '). - ''. - ($domainlevel{$priv}?'':' '). - ''. - ($systemlevel{$priv}?'':' '). - '
  '.&mt('User types:').'
' - .&selfenroll_inst_types($num,$currdom,\@currinsttypes).'
'.$add_domtitle.'
' .&Apache::loncommon::select_dom_form('','selfenroll_newdom', - $includeempty,$showdomdesc) + $includeempty,$showdomdesc,'',$trusted,$untrusted,$readonly) .'' .'
'."\n". ''."\n". '
'.&mt('Existing sections')."\n". '
'.$sections_select.'
'. &mt('New section').'
'."\n". - ''."\n". + ''."\n". ''."\n". - ''."\n". '
'."\n"; } elsif ($item eq 'approval') { - my ($appon,$appoff); - my $cid = $env{'request.course.id'}; - my $currnotified = $env{'course.'.$cid.'.internal.selfenroll_notifylist'}; - if ($env{'course.'.$cid.'.internal.selfenroll_approval'}) { - $appon = ' checked="checked" '; - $appoff = ' '; - } else { - $appon = ' '; - $appoff = ' checked="checked" '; + my ($currnotified,$currapproval,%appchecked); + my %selfdescs = &Apache::lonuserutils::selfenroll_default_descs(); + if (ref($currsettings) eq 'HASH') { + $currnotified = $currsettings->{'selfenroll_notifylist'}; + $currapproval = $currsettings->{'selfenroll_approval'}; + } + if ($currapproval !~ /^[012]$/) { + $currapproval = 0; + } + if ($noedit{$item}) { + $output .= $selfdescs{'approval'}{$currapproval}. + '
'.&mt('(Set by Domain Coordinator)'); + next; + } + $appchecked{$currapproval} = ' checked="checked"'; + for my $i (0..2) { + $output .= ''.(' 'x2); } - $output .= '  '; my %advhash = &Apache::lonnet::get_course_adv_roles($cid,1); my (@ccs,%notified); - if ($advhash{'cc'}) { - @ccs = split(/,/,$advhash{'cc'}); + my $ccrole = 'cc'; + if ($crstype eq 'Community') { + $ccrole = 'co'; + } + if ($advhash{$ccrole}) { + @ccs = split(/,/,$advhash{$ccrole}); } if ($currnotified) { foreach my $current (split(/,/,$currnotified)) { @@ -4158,7 +7508,13 @@ ENDSCRIPT } } if (@ccs) { - $output .= '
'.&mt('Personnel to be notified when an enrollment request needs approval, or has been approved:').' '.&Apache::loncommon::start_data_table(). + my $style; + unless ($currapproval) { + $style = ' style="display: none;"'; + } + $output .= '
'. + &mt('Personnel to be notified when an enrollment request needs approval, or has been approved:').' '. + &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_row(); my $count = 0; my $numcols = 4; @@ -4173,10 +7529,10 @@ ENDSCRIPT &Apache::loncommon::start_data_table_row() } $output .= ''; - $count; + $count ++; } my $rem = $count%$numcols; if ($rem) { @@ -4186,14 +7542,29 @@ ENDSCRIPT } } $output .= &Apache::loncommon::end_data_table_row(). - &Apache::loncommon::end_data_table(); + &Apache::loncommon::end_data_table(). + '
'; } } elsif ($item eq 'limit') { - my ($crslimit,$selflimit,$nolimit); - my $cid = $env{'request.course.id'}; - my $currlim = $env{'course.'.$cid.'.internal.selfenroll_limit'}; - my $currcap = $env{'course.'.$cid.'.internal.selfenroll_cap'}; - my $nolimit = ' checked="checked" '; + my ($crslimit,$selflimit,$nolimit,$currlim,$currcap); + if (ref($currsettings) eq 'HASH') { + $currlim = $currsettings->{'selfenroll_limit'}; + $currcap = $currsettings->{'selfenroll_cap'}; + } + if ($noedit{$item}) { + if (($currlim eq 'allstudents') || ($currlim eq 'selfenrolled')) { + if ($currlim eq 'allstudents') { + $output .= &mt('Limit by total students'); + } elsif ($currlim eq 'selfenrolled') { + $output .= &mt('Limit by total self-enrolled students'); + } + $output .= ' '.&mt('Maximum: [_1]',$currcap). + '
'.&mt('(Set by Domain Coordinator)'); + } else { + $output .= &mt('No limit').'
'.&mt('(Set by Domain Coordinator)'); + } + next; + } if ($currlim eq 'allstudents') { $crslimit = ' checked="checked" '; $selflimit = ' '; @@ -4205,334 +7576,73 @@ ENDSCRIPT } else { $crslimit = ' '; $selflimit = ' '; + $nolimit = ' checked="checked" '; } $output .= ''. '
 '. (' 'x3).&mt('Maximum number allowed: '). - '
'; + ''; } $output .= &Apache::lonhtmlcommon::row_closure(1); } } - $output .= &Apache::lonhtmlcommon::end_pick_box(). - '
' - .''; + $output .= &Apache::lonhtmlcommon::end_pick_box().'
'; + unless ($readonly) { + $output .= ''; + } + $output .= '' + .''."\n" + .$additional.''; $r->print($output); return; } -sub display_selfenroll_queue { - my ($r,$context,$permission,$cnum,$cdom) = @_; - my $namespace = 'selfenrollrequests'; - my ($output,%queue_by_date); - my %requesthash = &Apache::lonnet::dump($namespace,$cdom,$cnum); - if (keys(%requesthash) > 0) { - $r->print('
'. - ''. - ''. - &Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_header_row(). - ''.&mt('Action').''. - ''.&mt('Requestor').''. - ''.&mt('Section').''. - ''.&mt('Date requested').''. - &Apache::loncommon::end_data_table_header_row()); - foreach my $item (keys(%requesthash)) { - my ($timestamp,$usec) = split(/:/,$requesthash{$item}); - if (exists($queue_by_date{$timestamp})) { - if (ref($queue_by_date{$timestamp}) eq 'ARRAY') { - push(@{$queue_by_date{$timestamp}},$item.':'.$usec); - } - } else { - @{$queue_by_date{$timestamp}} = ($item.':'.$usec); - } - } - my @sortedtimes = sort {$a <=> $b} (keys(%queue_by_date)); - my $count = 0; - foreach my $item (@sortedtimes) { - if (ref($queue_by_date{$item}) eq 'ARRAY') { - foreach my $request (sort(@{$queue_by_date{$item}})) { - my ($puname,$pudom,$pusec) = split(/:/,$request); - my $showsec = $pusec; - if ($showsec eq '') { - $showsec = &mt('none'); - } - my $namelink = &Apache::loncommon::aboutmewrapper( - &Apache::loncommon::plainname($puname,$pudom), - $puname,$pudom); - $r->print(&Apache::loncommon::start_data_table_row(). - '
'. - '
'. - ''.$namelink.''. - ''.$showsec.''. - ''.&Apache::lonlocal::locallocaltime($item).''. - &Apache::loncommon::end_data_table_row()); - $count ++; - } - } - } - $r->print(&Apache::loncommon::end_data_table(). - '
'); - } else { - $r->print(&mt('There are currently no enrollment requests.')); - } - return; -} +sub get_noedit_fields { + my ($cdom,$cnum,$crstype,$row) = @_; + my %noedit; + if (ref($row) eq 'ARRAY') { + my %settings = &Apache::lonnet::get('environment',['internal.coursecode','internal.textbook', + 'internal.selfenrollmgrdc', + 'internal.selfenrollmgrcc'],$cdom,$cnum); + my $type = &Apache::lonuserutils::get_extended_type($cdom,$cnum,$crstype,\%settings); + my (%specific_managebydc,%specific_managebycc,%default_managebydc); + map { $specific_managebydc{$_} = 1; } (split(/,/,$settings{'internal.selfenrollmgrdc'})); + map { $specific_managebycc{$_} = 1; } (split(/,/,$settings{'internal.selfenrollmgrcc'})); + my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom); + map { $default_managebydc{$_} = 1; } (split(/,/,$domdefaults{$type.'selfenrolladmdc'})); -sub update_selfenroll_queue { - my ($r,$context,$permission,$cid,$cnum,$cdom) = @_; - my @approvals = &Apache::loncommon::get_env_multiple('form.approvereq'); - my @rejections = &Apache::loncommon::get_env_multiple('form.rejectreq'); - my $access_start = $env{'course.'.$cid.'.internal.selfenroll_start_access'}; - my $access_end = $env{'course.'.$cid.'.internal.selfenroll_end_access'}; - my $limit = $env{'course.'.$cid.'.internal.selfenroll_limit'}; - my $cap = $env{'course.'.$cid.'.internal.selfenroll_cap'}; - my $notifylist = $env{'course.'.$cid.'.internal.selfenroll_notifylist'}; - my $namespace = 'selfenrollrequests'; - my ($stucounts,$idx,$classlist) = &get_student_counts($cdom,$cnum); - my %requesthash = &Apache::lonnet::dump($namespace,$cdom,$cnum); - my $coursedesc = $env{'course.'.$cid.'.description'}; - my $chome = &Apache::lonnet::homeserver($cnum,$cdom); - my $hostname = &Apache::lonnet::hostname($chome); - my $protocol = $Apache::lonnet::protocol{$chome}; - $protocol = 'http' if ($protocol ne 'https'); - my (@existing,@missingreq,@invalidusers,@limitexceeded,@enrolled, - @enrollerrors,@warn_approves,@warn_rejects); - my $now = time; - my $sender = $env{'user.name'}.':'.$env{'user.domain'}; - my $approvedmsg = [{ - mt => 'Your request for enrollment has been approved.', - }, - { - mt => 'Visit [_1], to log-in and access the course', - args => [$protocol.'://'.$hostname], - }]; - - my $rejectedmsg = [{ - mt => 'Your request for enrollment has not been approved.', - }]; - foreach my $item (sort {$a <=> $b} @approvals) { - my ($num,$uname,$udom,$usec) = split(/:/,$item); - my $uhome = &Apache::lonnet::homeserver($uname,$udom); - if ($uhome ne 'no_host') { - if (exists($requesthash{$uname.':'.$udom})) { - - if (exists($classlist->{$uname.':'.$udom})) { - if (ref($classlist->{$uname.':'.$udom}) eq 'ARRAY') { - if (($classlist->{$uname.':'.$udom}->[$idx->{'status'}] eq 'Active') || - ($classlist->{$uname.':'.$udom}->[$idx->{'status'}] eq 'Future')) { - push(@existing,$uname.':'.$udom); - next; - } - } - } - } else { - push(@missingreq,$uname.':'.$udom); - next; - } - if (!grep(/^\Q$item\E$/,@rejections)) { - if ($limit eq 'allstudents') { - if ($stucounts->{$limit} >= $cap) { - push(@limitexceeded,$uname.':'.$udom); - last; - } - } elsif ($limit eq 'selfenrolled') { - if ($stucounts->{$limit} >= $cap) { - push(@limitexceeded,$uname.':'.$udom); - last; - } - } - my $result = - &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$usec,$access_end,$access_start,'selfenroll',undef,$cdom.'_'.$cnum,1); - if ($result eq 'ok') { - push(@enrolled,$uname.':'.$udom); - $stucounts->{'allstudents'} ++; - $stucounts->{'selfenrolled'} ++; - &Apache::selfenroll::send_notification($uname.':'.$udom,$approvedmsg,$cid, - $coursedesc,$now,'enroller',$sender); - my %userrequest = ( - $cdom.'_'.$cnum => { - timestamp => $now, - section => $usec, - adjudicator => $env{'user.name'}.':'.$env{'user.domain'}, - status => 'approved', - } - ); - my $userresult = - &Apache::lonnet::put($namespace,\%userrequest,$udom,$uname); - if ($userresult ne 'ok') { - push(@warn_approves,$uname.':'.$udom); - } - } else { - push(@enrollerrors,$uname.':'.$udom); - } - } - } else { - push(@invalidusers,$uname.':'.$udom); - } - } - my @changes = (@enrolled,@rejections); - if (@rejections) { - foreach my $user (@rejections) { - &Apache::selfenroll::send_notification($user,$rejectedmsg,$cid, - $coursedesc,$now,'enroller',$sender); - my ($uname,$udom) = split(/:/,$user); - my %userrequest = ( - $cdom.'_'.$cnum => { - timestamp => $now, - adjudicator => $env{'user.name'}.':'.$env{'user.domain'}, - status => 'rejected', - } - ); - my $userresult = - &Apache::lonnet::put($namespace,\%userrequest,$udom,$uname); - if ($userresult ne 'ok') { - push(@warn_rejects,$user); - } - } - } - if (@changes) { - my $delresult = &Apache::lonnet::del($namespace,\@changes,$cdom,$cnum); - if ($delresult eq 'ok') { - my $namelink = - &Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}).' ('.$env{'user.name'}.':'.$env{'user.domain'}.')'; - my $chgmsg = "'Action was taken on the following enrollment requests by [_1].',$namelink"; - my ($approvedlist,$rejectedlist); - if (@enrolled) { - $approvedlist = join("\n",@enrolled); - $r->print('

'.&mt('The following were enrolled in the course:').'

    '); - foreach my $user (@enrolled) { - my ($uname,$udom) = split(/:/,$user); - my $userlink = - &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom); - $r->print('
  • '.$userlink.'
  • '); - } - $r->print('

'); - } - if (@rejections) { - $rejectedlist = join("\n",@rejections); - $r->print('

'.&mt('The following enrollment requests were rejected:').'

    '); - foreach my $user (@rejections) { - $r->print('
  • '.$user.'
  • '); - } - $r->print('

'); + foreach my $item (@{$row}) { + next if ($specific_managebycc{$item}); + if (($specific_managebydc{$item}) || ($default_managebydc{$item})) { + $noedit{$item} = 1; } - &Apache::selfenroll::send_notification($notifylist,$chgmsg,$cid, - $coursedesc,$now,'managers', - $sender,$approvedlist,$rejectedlist); - } - } - if (@existing) { - $r->print('

'.&mt('The following enrollment requests were deleted because the user is already enrolled in the course:').'

    '); - foreach my $user (@existing) { - $r->print('
  • '.$user.'
  • '); - } - $r->print('

'); - } - if (@missingreq) { - $r->print('

'.&mt('The following enrollment requests were ignored because the request is no longer in the enrollment queue:').'

    '); - foreach my $user (@missingreq) { - $r->print('
  • '.$user.'
  • '); - } - $r->print('

'); - } - if (@invalidusers) { - $r->print('

'.&mt('The following enrollment requests were deleted because the requestor does not have a LON-CAPA account:').'

    '); - foreach my $user (@invalidusers) { - $r->print('
  • '.$user.'
  • '); - } - $r->print('

'); - } - if (@limitexceeded) { - $r->print('

'.&mt('The following enrollment requests were skipped because the enrollment limit has been reached for the course:').'

    '); - foreach my $user (@limitexceeded) { - $r->print('
  • '.$user.'
  • '); - } - $r->print('

'); - } - if (@enrollerrors) { - $r->print('

'.&mt('The following enrollment requests could not be processed because an error occurred:').'

    '); - foreach my $user (@enrollerrors) { - $r->print('
  • '.$user.'
  • '); } - $r->print('

'); } - if (@warn_approves) { - $r->print('

'.&mt("For the following users, an error occurred when updating the user's own self-enroll requests record:").'

    '); - foreach my $user (@warn_approves) { - $r->print('
  • '.$user.'
  • '); - } - $r->print('

'); - } - if (@warn_rejects) { - $r->print('

'.&mt("For the following users, an error occurred when updating the user's own self-enroll requests record:").'

    '); - foreach my $user (@warn_rejects) { - $r->print('
  • '.$user.'
  • '); - } - $r->print('

'); - } - return; + return %noedit; } -sub get_student_counts { - my ($cdom,$cnum) = @_; - my (%idx,%stucounts); - my $classlist = &Apache::loncoursedata::get_classlist($cdom,$cnum); - $idx{'type'} = &Apache::loncoursedata::CL_TYPE(); - $idx{'status'} = &Apache::loncoursedata::CL_STATUS(); - while (my ($student,$data) = each(%$classlist)) { - if (($data->[$idx{'status'}] eq 'Active') || - ($data->[$idx{'status'}] eq 'Future')) { - if ($data->[$idx{'type'}] eq 'selfenroll') { - $stucounts{'selfenroll'} ++; - } - $stucounts{'allstudents'} ++; - } - } - return (\%stucounts,\%idx,$classlist); -} - -sub visible_in_cat { - my ($cdom,$cnum) = @_; - my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom); - my ($cathash,%settable,@vismsgs,$cansetvis); - my %visactions = &Apache::lonlocal::texthash( - vis => 'Your course currently appears in the Course Catalog for this domain.', - gen => 'Courses can be both self-cataloging, based on an institutional code (e.g., fs08phy231), or can be assigned categories from a hierarchy defined for the domain.', - miss => 'Your course does not currently appear in the Course Catalog for this domain.', - yous => 'You should remedy this if you plan to allow self-enrollment, otherwise students will have difficulty finding your course.', - coca => 'Courses can be absent from the Catalog, because they do not have an institutional code, have no assigned category, or have been specifically excluded.', - make => 'Make any changes to self-enrollment settings below, click "Save", then take action to include the course in the Catalog:', - take => 'Take the following action to ensure the course appears in the Catalog:', - dc_unhide => 'Ask a domain coordinator to change the "Exclude from course catalog" setting.', - dc_addinst => 'Ask a domain coordinator to enable display the catalog of "Official courses (with institutional codes)".', - dc_instcode => 'Ask a domain coordinator to assign an institutional code (if this is an official course).', - dc_catalog => 'Ask a domain coordinator to enable or create at least one course category in the domain.', - dc_categories => 'Ask a domain coordinator to create a hierarchy of categories and sub categories for courses in the domain.', - dc_chgcat => 'Ask a domain coordinator to change the category assigned to the course, as the one currently assigned is no longer used in the domain', - dc_addcat => 'Ask a domain coordinator to assign a category to the course.', - ); - $visactions{'unhide'} = &mt('Use [_1]Set course environment[_2] to change the "Exclude from course catalog" setting.','"','"'); - $visactions{'chgcat'} = &mt('Use [_1]Set course environment[_2] to change the category assigned to the course, as the one currently assigned is no longer used in the domain.','"','"'); - $visactions{'addcat'} = &mt('Use [_1]Set course environment[_2] to assign a category to the course.','"','"'); - if (ref($domconf{'coursecategories'}) eq 'HASH') { - if ($domconf{'coursecategories'}{'togglecats'} eq 'crs') { +sub visible_in_stdcat { + my ($cdom,$cnum,$domconf) = @_; + my ($cathash,%settable,@vismsgs,$cansetvis,$visible); + unless (ref($domconf) eq 'HASH') { + return ($visible,$cansetvis,\@vismsgs); + } + if (ref($domconf->{'coursecategories'}) eq 'HASH') { + if ($domconf->{'coursecategories'}{'togglecats'} eq 'crs') { $settable{'togglecats'} = 1; } - if ($domconf{'coursecategories'}{'categorize'} eq 'crs') { + if ($domconf->{'coursecategories'}{'categorize'} eq 'crs') { $settable{'categorize'} = 1; } - $cathash = $domconf{'coursecategories'}{'cats'}; + $cathash = $domconf->{'coursecategories'}{'cats'}; } if ($settable{'togglecats'} && $settable{'categorize'}) { $cansetvis = &mt('You are able to both assign a course category and choose to exclude this course from the catalog.'); @@ -4547,10 +7657,10 @@ sub visible_in_cat { my %currsettings = &Apache::lonnet::get('environment',['hidefromcat','categories','internal.coursecode'], $cdom,$cnum); - my $visible = 0; + $visible = 0; if ($currsettings{'internal.coursecode'} ne '') { - if (ref($domconf{'coursecategories'}) eq 'HASH') { - $cathash = $domconf{'coursecategories'}{'cats'}; + if (ref($domconf->{'coursecategories'}) eq 'HASH') { + $cathash = $domconf->{'coursecategories'}{'cats'}; if (ref($cathash) eq 'HASH') { if ($cathash->{'instcode::0'} eq '') { push(@vismsgs,'dc_addinst'); @@ -4574,8 +7684,8 @@ sub visible_in_cat { } if ($currsettings{'categories'} ne '') { my $cathash; - if (ref($domconf{'coursecategories'}) eq 'HASH') { - $cathash = $domconf{'coursecategories'}{'cats'}; + if (ref($domconf->{'coursecategories'}) eq 'HASH') { + $cathash = $domconf->{'coursecategories'}{'cats'}; if (ref($cathash) eq 'HASH') { if (keys(%{$cathash}) == 0) { push(@vismsgs,'dc_catalog'); @@ -4621,7 +7731,45 @@ sub visible_in_cat { unshift(@vismsgs,'dc_unhide') } } - return ($visible,$cansetvis,\@vismsgs,\%visactions); + return ($visible,$cansetvis,\@vismsgs); +} + +sub cat_visibility { + my ($cdom) = @_; + my %visactions = &Apache::lonlocal::texthash( + vis => 'This course/community currently appears in the Course/Community Catalog for this domain.', + gen => 'Courses can be both self-cataloging, based on an institutional code (e.g., fs08phy231), or can be assigned categories from a hierarchy defined for the domain.', + miss => 'This course/community does not currently appear in the Course/Community Catalog for this domain.', + none => 'Display of a course catalog is disabled for this domain.', + yous => 'You should remedy this if you plan to allow self-enrollment, otherwise students will have difficulty finding this course.', + coca => 'Courses can be absent from the Catalog, because they do not have an institutional code, have no assigned category, or have been specifically excluded.', + make => 'Make any changes to self-enrollment settings below, click "Save", then take action to include the course in the Catalog:', + take => 'Take the following action to ensure the course appears in the Catalog:', + dc_chgconf => 'Ask a domain coordinator to change the Catalog type for this domain.', + dc_setcode => 'Ask a domain coordinator to assign a six character code to the course', + dc_unhide => 'Ask a domain coordinator to change the "Exclude from course catalog" setting.', + dc_addinst => 'Ask a domain coordinator to enable catalog display of "Official courses (with institutional codes)".', + dc_instcode => 'Ask a domain coordinator to assign an institutional code (if this is an official course).', + dc_catalog => 'Ask a domain coordinator to enable or create at least one course category in the domain.', + dc_categories => 'Ask a domain coordinator to create a hierarchy of categories and sub categories for courses in the domain.', + dc_chgcat => 'Ask a domain coordinator to change the category assigned to the course, as the one currently assigned is no longer used in the domain', + dc_addcat => 'Ask a domain coordinator to assign a category to the course.', + ); + if ($env{'request.role'} eq "dc./$cdom/") { + $visactions{'dc_chgconf'} = &mt('Use: "Main menu" [_1] "Set domain configuration" [_1] "Cataloging of courses/communities" to change the Catalog type for this domain.','»'); + $visactions{'dc_setcode'} = &mt('Use: "Main menu" [_1] "Set domain configuration" [_1] "Cataloging of courses/communities" to assign a six character code to the course.','»'); + $visactions{'dc_unhide'} = &mt('Use: "Main menu" [_1] "Set domain configuration" [_1] "Cataloging of courses/communities" to change the "Exclude from course catalog" setting.','»'); + $visactions{'dc_addinst'} = &mt('Use: "Main menu" [_1] "Set domain configuration" [_1] "Cataloging of courses/communities" to enable catalog display of "Official courses (with institutional codes)".','»'); + $visactions{'dc_instcode'} = &mt('Use: "Main menu" [_1] "View or modify a course or community" [_1] "View/Modify course owner, institutional code ... " to assign an institutional code (if this is an official course).','»'); + $visactions{'dc_catalog'} = &mt('Use: "Main menu" [_1] "Set domain configuration" [_1] "Cataloging of courses/communities" to enable or create at least one course category in the domain.','»'); + $visactions{'dc_categories'} = &mt('Use: "Main menu" [_1] "Set domain configuration" [_1] "Cataloging of courses/communities" to create a hierarchy of categories and sub categories for courses in the domain.','»'); + $visactions{'dc_chgcat'} = &mt('Use: "Main menu" [_1] "View or modify a course or community" [_1] "View/Modify catalog settings for course" to change the category assigned to the course, as the one currently assigned is no longer used in the domain.','»'); + $visactions{'dc_addcat'} = &mt('Use: "Main menu" [_1] "View or modify a course or community" [_1] "View/Modify catalog settings for course" to assign a category to the course.','»'); + } + $visactions{'unhide'} = &mt('Use [_1]Categorize course[_2] to change the "Exclude from course catalog" setting.','','"'); + $visactions{'chgcat'} = &mt('Use [_1]Categorize course[_2] to change the category assigned to the course, as the one currently assigned is no longer used in the domain.','"','"'); + $visactions{'addcat'} = &mt('Use [_1]Categorize course[_2] to assign a category to the course.','"','"'); + return \%visactions; } sub new_selfenroll_dom_row { @@ -4647,12 +7795,16 @@ sub new_selfenroll_dom_row { } sub selfenroll_inst_types { - my ($num,$currdom,$currinsttypes) = @_; + my ($num,$currdom,$currinsttypes,$readonly) = @_; my $output; my $numinrow = 4; my $count = 0; my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($currdom); my $othervalue = 'any'; + my $disabled; + if ($readonly) { + $disabled = ' disabled="disabled"'; + } if ((ref($types) eq 'ARRAY') && (ref($usertypes) eq 'HASH')) { if (keys(%{$usertypes}) > 0) { $othervalue = 'other'; @@ -4677,7 +7829,7 @@ sub selfenroll_inst_types { $output .= 'checked="checked"'; } } - $output .= ' name="selfenroll_types_'.$num.'" />'.$usertypes->{$type}.''; + $output .= ' name="selfenroll_types_'.$num.'"'.$disabled.' />'.$usertypes->{$type}.''; } $count ++; } @@ -4700,7 +7852,7 @@ sub selfenroll_inst_types { } else { $output .= ' checked="checked"'; } - $output .= ' name="selfenroll_types_'.$num.'" />'.$othertitle.''; + $output .= ' name="selfenroll_types_'.$num.'"'.$disabled.' />'.$othertitle.''; } return $output; } @@ -4721,19 +7873,69 @@ sub selfenroll_date_forms { } sub print_userchangelogs_display { - my ($r,$context,$permission) = @_; - my $formname = 'roleslog'; - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my %roleslog=&Apache::lonnet::dump('nohist_rolelog',$cdom,$cnum); + my ($r,$context,$permission,$brcrum) = @_; + my $formname = 'rolelog'; + my ($username,$domain,$crstype,$viewablesec,%roleslog); + if ($context eq 'domain') { + $domain = $env{'request.role.domain'}; + %roleslog=&Apache::lonnet::dump_dom('nohist_rolelog',$domain); + } else { + if ($context eq 'course') { + $domain = $env{'course.'.$env{'request.course.id'}.'.domain'}; + $username = $env{'course.'.$env{'request.course.id'}.'.num'}; + $crstype = &Apache::loncommon::course_type(); + $viewablesec = &Apache::lonuserutils::viewable_section($permission); + my %saveable_parameters = ('show' => 'scalar',); + &Apache::loncommon::store_course_settings('roles_log', + \%saveable_parameters); + &Apache::loncommon::restore_course_settings('roles_log', + \%saveable_parameters); + } elsif ($context eq 'author') { + $domain = $env{'user.domain'}; + if ($env{'request.role'} =~ m{^au\./\Q$domain\E/$}) { + $username = $env{'user.name'}; + } elsif ($env{'request.role'} =~ m{^ca\./($match_domain)/($match_username)$}) { + ($domain,$username) = ($1,$2); + } else { + undef($domain); + } + } + if ($domain ne '' && $username ne '') { + %roleslog=&Apache::lonnet::dump('nohist_rolelog',$domain,$username); + } + } if ((keys(%roleslog))[0]=~/^error\:/) { undef(%roleslog); } - $r->print('
'); - my %saveable_parameters = ('show' => 'scalar',); - &Apache::loncommon::store_course_settings('roles_log', - \%saveable_parameters); - &Apache::loncommon::restore_course_settings('roles_log', - \%saveable_parameters); + my $helpitem; + if ($context eq 'course') { + $helpitem = 'Course_User_Logs'; + } elsif ($context eq 'domain') { + $helpitem = 'Domain_Role_Logs'; + } elsif ($context eq 'author') { + $helpitem = 'Author_User_Logs'; + } + push (@{$brcrum}, + {href => '/adm/createuser?action=changelogs', + text => 'User Management Logs', + help => $helpitem}); + my $bread_crumbs_component = 'User Changes'; + my $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + + # Create navigation javascript + my $jsnav = &userlogdisplay_js($formname); + + my $jscript = (< +// + +ENDSCRIPT + + # print page header + $r->print(&header($jscript,$args)); + # set defaults my $now = time(); my $defstart = $now - (7*24*3600); #7 days ago @@ -4744,12 +7946,13 @@ sub print_userchangelogs_display { chgcontext => 'any', rolelog_start_date => $defstart, rolelog_end_date => $now, + approvals => 'any', ); my $more_records = 0; # set current my %curr; - foreach my $item ('show','page','role','chgcontext') { + foreach my $item ('show','page','role','chgcontext','approvals') { $curr{$item} = $env{'form.'.$item}; } my ($startdate,$enddate) = @@ -4763,27 +7966,48 @@ sub print_userchangelogs_display { } my (%whodunit,%changed,$version); ($version) = ($r->dir_config('lonVersion') =~ /^([\d\.]+)\-/); - $r->print(&role_display_filter($formname,$cdom,$cnum,\%curr,$version)); - my $showntablehdr = 0; - my $tablehdr = &Apache::loncommon::start_data_table(). - &Apache::loncommon::start_data_table_header_row(). - ' '.&mt('When').''.&mt('Who made the change'). - ''.&mt('Changed User').''.&mt('Role').''.&mt('Section').''. - &mt('Context').''.&mt('Start').''.&mt('End').''. - &Apache::loncommon::end_data_table_header_row(); my ($minshown,$maxshown); $minshown = 1; my $count = 0; - if ($curr{'show'} ne &mt('all')) { + if ($curr{'show'} =~ /\D/) { + $curr{'page'} = 1; + } else { $maxshown = $curr{'page'} * $curr{'show'}; if ($curr{'page'} > 1) { $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'}; } } + + # Form Header + $r->print(''. + &role_display_filter($context,$formname,$domain,$username,\%curr, + $version,$crstype)); + + my $showntableheader = 0; + + # Table Header + my $tableheader = + &Apache::loncommon::start_data_table_header_row() + .' ' + .''.&mt('When').'' + .''.&mt('Who made the change').'' + .''.&mt('Changed User').'' + .''.&mt('Role').''; + + if ($context eq 'course') { + $tableheader .= ''.&mt('Section').''; + } + $tableheader .= + ''.&mt('Context').'' + .''.&mt('Start').'' + .''.&mt('End').'' + .&Apache::loncommon::end_data_table_header_row(); + + # Display user change log data foreach my $id (sort { $roleslog{$b}{'exe_time'}<=>$roleslog{$a}{'exe_time'} } (keys(%roleslog))) { next if (($roleslog{$id}{'exe_time'} < $curr{'rolelog_start_date'}) || ($roleslog{$id}{'exe_time'} > $curr{'rolelog_end_date'})); - if ($curr{'show'} ne &mt('all')) { + if ($curr{'show'} !~ /\D/) { if ($count >= $curr{'page'} * $curr{'show'}) { $more_records = 1; last; @@ -4799,11 +8023,21 @@ sub print_userchangelogs_display { next if ($roleslog{$id}{'logentry'}{'context'} ne $curr{'chgcontext'}); } } + if (($context eq 'course') && ($viewablesec ne '')) { + next if ($roleslog{$id}{'logentry'}{'section'} ne $viewablesec); + } + if ($curr{'approvals'} eq 'none') { + next if ($roleslog{$id}{'logentry'}{'approval'}); + } elsif ($curr{'approvals'} ne 'any') { + next if ($roleslog{$id}{'logentry'}{'approval'} ne $curr{'approvals'}); + } $count ++; next if ($count < $minshown); - if (!$showntablehdr) { - $r->print($tablehdr); - $showntablehdr = 1; + unless ($showntableheader) { + $r->print(&Apache::loncommon::start_data_table() + .$tableheader); + $r->rflush(); + $showntableheader = 1; } if ($whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}} eq '') { $whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}} = @@ -4839,25 +8073,436 @@ sub print_userchangelogs_display { if ($roleslog{$id}{'logentry'}{'selfenroll'}) { $chgcontext = 'selfenroll'; } - my %lt = &rolechg_contexts(); + my %lt = &rolechg_contexts($context,$crstype); if ($chgcontext ne '' && $lt{$chgcontext} ne '') { $chgcontext = $lt{$chgcontext}; } - $r->print(&Apache::loncommon::start_data_table_row().''.$count.''.&Apache::lonlocal::locallocaltime($roleslog{$id}{'exe_time'}).''.$whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}}.''.$changed{$roleslog{$id}{'uname'}.':'.$roleslog{$id}{'udom'}}.''.&Apache::lonnet::plaintext($roleslog{$id}{'logentry'}{'role'}).''.$sec.''.$chgcontext.''.$rolestart.''.$roleend.''.&Apache::loncommon::end_data_table_row()."\n"); - } - if ($showntablehdr) { - $r->print(&Apache::loncommon::end_data_table().'
'); - if (($curr{'page'} > 1) || ($more_records)) { - $r->print(''); - if ($curr{'page'} > 1) { - $r->print(''); + my ($showreqby,%reqby); + if (($roleslog{$id}{'logentry'}{'approval'}) && + ($roleslog{$id}{'logentry'}{'requester'})) { + if ($reqby{$roleslog{$id}{'logentry'}{'requester'}} eq '') { + my ($requname,$requdom) = split(/:/,$roleslog{$id}{'logentry'}{'requester'}); + $reqby{$roleslog{$id}{'logentry'}{'requester'}} = + &Apache::loncommon::plainname($requname,$requdom); + } + $showreqby = &mt('Requester').': '.$reqby{$roleslog{$id}{'logentry'}{'requester'}}.'
'; + if ($roleslog{$id}{'logentry'}{'approval'} eq 'domain') { + $showreqby .= &mt('Adjudicator').': '. + $whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}}. + ''; + } else { + $showreqby .= ''.&mt('User approved').''; } - if ($more_records) { - $r->print(''); + } else { + $showreqby = $whodunit{$roleslog{$id}{'exe_uname'}.':'.$roleslog{$id}{'exe_udom'}}; + } + $r->print( + &Apache::loncommon::start_data_table_row() + .'' + .'' + .'' + .'' + .''); + if ($context eq 'course') { + $r->print(''); + } + $r->print( + '' + .'' + .'' + .&Apache::loncommon::end_data_table_row()."\n"); + } + + if ($showntableheader) { # Table footer, if content displayed above + $r->print(&Apache::loncommon::end_data_table(). + &userlogdisplay_navlinks(\%curr,$more_records)); + } else { # No content displayed above + $r->print('

' + .&mt('There are no records to display.') + .'

' + ); + } + + # Form Footer + $r->print( + '' + .'' + .''); + return; +} + +sub print_useraccesslogs_display { + my ($r,$uname,$udom,$permission,$brcrum) = @_; + my $formname = 'accesslog'; + my $form = 'document.accesslog'; + +# set breadcrumbs + my %breadcrumb_text = &singleuser_breadcrumb('','domain',$udom); + my $prevphasestr; + if ($env{'form.popup'}) { + $brcrum = []; + } else { + push (@{$brcrum}, + {href => "javascript:backPage($form)", + text => $breadcrumb_text{'search'}}); + my @prevphases; + if ($env{'form.prevphases'}) { + @prevphases = split(/,/,$env{'form.prevphases'}); + $prevphasestr = $env{'form.prevphases'}; + } + if (($env{'form.phase'} eq 'userpicked') || (grep(/^userpicked$/,@prevphases))) { + push(@{$brcrum}, + {href => "javascript:backPage($form,'get_user_info','select')", + text => $breadcrumb_text{'userpicked'}}); + if ($env{'form.phase'} eq 'userpicked') { + $prevphasestr = 'userpicked'; } - $r->print('
'.&mt('Previous [_1] changes',$curr{'show'}).''.&mt('Next [_1] changes',$curr{'show'}).''.$count.''.&Apache::lonlocal::locallocaltime($roleslog{$id}{'exe_time'}).''.$showreqby.''.$changed{$roleslog{$id}{'uname'}.':'.$roleslog{$id}{'udom'}}.''.&Apache::lonnet::plaintext($roleslog{$id}{'logentry'}{'role'},$crstype).''.$sec.''.$chgcontext.''.$rolestart.''.$roleend.'
'); - $r->print(<<"ENDSCRIPT"); + } + } + push(@{$brcrum}, + {href => '/adm/createuser?action=accesslogs', + text => 'User access logs', + help => 'Domain_User_Access_Logs'}); + my $bread_crumbs_component = 'User Access Logs'; + my $args = { bread_crumbs => $brcrum, + bread_crumbs_component => 'User Management'}; + if ($env{'form.popup'}) { + $args->{'no_nav_bar'} = 1; + $args->{'bread_crumbs_nomenu'} = 1; + } + +# set javascript + my ($jsback,$elements) = &crumb_utilities(); + my $jsnav = &userlogdisplay_js($formname); + + my $jscript = (< +// + + +ENDSCRIPT + +# print page header + $r->print(&header($jscript,$args)); + +# early out unless log data can be displayed. + unless ($permission->{'activity'}) { + $r->print('

' + .&mt('You do not have rights to display user access logs.') + .'

'); + if ($env{'form.popup'}) { + $r->print('

'.&mt('Close window').'

'); + } else { + $r->print(&earlyout_accesslog_form($formname,$prevphasestr,$udom)); + } + return; + } + + unless ($udom eq $env{'request.role.domain'}) { + $r->print('

' + .&mt("User's domain must match role's domain") + .'

' + .&earlyout_accesslog_form($formname,$prevphasestr,$udom)); + return; + } + + if (($uname eq '') || ($udom eq '')) { + $r->print('

' + .&mt('Invalid username or domain') + .'

' + .&earlyout_accesslog_form($formname,$prevphasestr,$udom)); + return; + } + + if (&Apache::lonnet::privileged($uname,$udom, + [$env{'request.role.domain'}],['dc','su'])) { + unless (&Apache::lonnet::privileged($env{'user.name'},$env{'user.domain'}, + [$env{'request.role.domain'}],['dc','su'])) { + $r->print('

' + .&mt('You need to be a privileged user to display user access logs for [_1]', + &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom), + $uname,$udom)) + .'

'); + if ($env{'form.popup'}) { + $r->print('

'.&mt('Close window').'

'); + } else { + $r->print(&earlyout_accesslog_form($formname,$prevphasestr,$udom)); + } + return; + } + } + +# set defaults + my $now = time(); + my $defstart = $now - (7*24*3600); + my %defaults = ( + page => '1', + show => '10', + activity => 'any', + accesslog_start_date => $defstart, + accesslog_end_date => $now, + ); + my $more_records = 0; + +# set current + my %curr; + foreach my $item ('show','page','activity') { + $curr{$item} = $env{'form.'.$item}; + } + my ($startdate,$enddate) = + &Apache::lonuserutils::get_dates_from_form('accesslog_start_date','accesslog_end_date'); + $curr{'accesslog_start_date'} = $startdate; + $curr{'accesslog_end_date'} = $enddate; + foreach my $key (keys(%defaults)) { + if ($curr{$key} eq '') { + $curr{$key} = $defaults{$key}; + } + } + my ($minshown,$maxshown); + $minshown = 1; + my $count = 0; + if ($curr{'show'} =~ /\D/) { + $curr{'page'} = 1; + } else { + $maxshown = $curr{'page'} * $curr{'show'}; + if ($curr{'page'} > 1) { + $minshown = 1 + ($curr{'page'} - 1) * $curr{'show'}; + } + } + +# form header + $r->print('
'. + &activity_display_filter($formname,\%curr)); + + my $showntableheader = 0; + my ($nav_script,$nav_links); + +# table header + my $heading = '

'. + &mt('User access logs for: [_1]', + &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom)).'

'; + my $tableheader = $heading + .&Apache::loncommon::start_data_table_header_row() + .' ' + .''.&mt('When').'' + .''.&mt('HostID').'' + .''.&mt('Event').'' + .''.&mt('Other data').'' + .&Apache::loncommon::end_data_table_header_row(); + + my %filters=( + start => $curr{'accesslog_start_date'}, + end => $curr{'accesslog_end_date'}, + action => $curr{'activity'}, + ); + + my $reply = &Apache::lonnet::userlog_query($uname,$udom,%filters); + unless ( ($reply =~/^timeout/) || ($reply =~/^error/) ) { + my (%courses,%missing); + my @results = split(/\&/,$reply); + foreach my $item (reverse(@results)) { + my ($timestamp,$host,$event) = split(/:/,$item); + next unless ($event =~ /^(Log|Role)/); + if ($curr{'show'} !~ /\D/) { + if ($count >= $curr{'page'} * $curr{'show'}) { + $more_records = 1; + last; + } + } + $count ++; + next if ($count < $minshown); + unless ($showntableheader) { + $r->print($nav_script + .&Apache::loncommon::start_data_table() + .$tableheader); + $r->rflush(); + $showntableheader = 1; + } + my ($shown,$extra); + my ($event,$data) = split(/\s+/,&unescape($event),2); + if ($event eq 'Role') { + my ($rolecode,$extent) = split(/\./,$data,2); + next if ($extent eq ''); + my ($crstype,$desc,$info); + if ($extent =~ m{^/($match_domain)/($match_courseid)(?:/(\w+)|)$}) { + my ($cdom,$cnum,$sec) = ($1,$2,$3); + my $cid = $cdom.'_'.$cnum; + if (exists($courses{$cid})) { + $crstype = $courses{$cid}{'type'}; + $desc = $courses{$cid}{'description'}; + } elsif ($missing{$cid}) { + $crstype = 'Course'; + $desc = 'Course/Community'; + } else { + my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.',$cnum,undef,undef,'.'); + if (ref($crsinfo{$cdom.'_'.$cnum}) eq 'HASH') { + $courses{$cid} = $crsinfo{$cid}; + $crstype = $crsinfo{$cid}{'type'}; + $desc = $crsinfo{$cid}{'description'}; + } else { + $missing{$cid} = 1; + } + } + $extra = &mt($crstype).': '.$desc.''; + if ($sec ne '') { + $extra .= ' ('.&mt('Section: [_1]',$sec).')'; + } + } elsif ($extent =~ m{^/($match_domain)/($match_username|$)}) { + my ($dom,$name) = ($1,$2); + if ($rolecode eq 'au') { + $extra = ''; + } elsif ($rolecode =~ /^(ca|aa)$/) { + $extra = &mt('Authoring Space: [_1]',$name.':'.$dom); + } elsif ($rolecode =~ /^(li|dg|dh|dc|sc)$/) { + $extra = &mt('Domain: [_1]',$dom); + } + } + my $rolename; + if ($rolecode =~ m{^cr/($match_domain)/($match_username)/(\w+)}) { + my $role = $3; + my $owner = "($2:$1)"; + if ($2 eq $1.'-domainconfig') { + $owner = '(ad hoc)'; + } + $rolename = &mt('Custom role: [_1]',$role.' '.$owner); + } else { + $rolename = &Apache::lonnet::plaintext($rolecode,$crstype); + } + $shown = &mt('Role selection: [_1]',$rolename); + } else { + $shown = &mt($event); + if ($data =~ /^webdav/) { + my ($path,$clientip) = split(/\s+/,$data,2); + $path =~ s/^webdav//; + if ($clientip ne '') { + $extra = &mt('Client IP address: [_1]',$clientip); + } + if ($path ne '') { + $shown .= ' '.&mt('(WebDAV access to [_1])',$path); + } + } elsif ($data ne '') { + $extra = &mt('Client IP address: [_1]',$data); + } + } + $r->print( + &Apache::loncommon::start_data_table_row() + .''.$count.'' + .''.&Apache::lonlocal::locallocaltime($timestamp).'' + .''.$host.'' + .''.$shown.'' + .''.$extra.'' + .&Apache::loncommon::end_data_table_row()."\n"); + } + } + + if ($showntableheader) { # Table footer, if content displayed above + $r->print(&Apache::loncommon::end_data_table(). + &userlogdisplay_navlinks(\%curr,$more_records)); + } else { # No content displayed above + $r->print($heading.'

' + .&mt('There are no records to display.') + .'

'); + } + + if ($env{'form.popup'} == 1) { + $r->print(''."\n"); + } + + # Form Footer + $r->print( + '' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'
'); + return; +} + +sub earlyout_accesslog_form { + my ($formname,$prevphasestr,$udom) = @_; + my $srchterm = &HTML::Entities::encode($env{'form.srchterm'},'<>"&'); + return <<"END"; +
+ + + + + + + + + +
+END +} + +sub activity_display_filter { + my ($formname,$curr) = @_; + my $nolink = 1; + my $output = ''; + my $startform = + &Apache::lonhtmlcommon::date_setter($formname,'accesslog_start_date', + $curr->{'accesslog_start_date'},undef, + undef,undef,undef,undef,undef,undef,$nolink); + my $endform = + &Apache::lonhtmlcommon::date_setter($formname,'accesslog_end_date', + $curr->{'accesslog_end_date'},undef, + undef,undef,undef,undef,undef,undef,$nolink); + my %lt = &Apache::lonlocal::texthash ( + activity => 'Activity', + Role => 'Role selection', + log => 'Log-in or Logout', + ); + $output .= ''. + ''. + ''. + '
'. + ''.&mt('Actions/page:').'
'. + &Apache::lonmeta::selectbox('show',$curr->{'show'},'',undef, + (&mt('all'),5,10,20,50,100,1000,10000)). + '
  '.&mt('Window during which actions occurred:').'
'. + ''. + ''. + '
'.&mt('After:'). + ''.$startform.'
'.&mt('Before:').''.$endform.'
'. + '
  '.&mt('Activities').'
'. + '
'; + # Update Display button + $output .= '

' + .'' + .'


'; + return $output; +} + +sub userlogdisplay_js { + my ($formname) = @_; + return <<"ENDSCRIPT"; + function chgPage(caller) { if (caller == 'previous') { document.$formname.page.value --; @@ -4865,27 +8510,41 @@ function chgPage(caller) { if (caller == 'next') { document.$formname.page.value ++; } - document.$formname.submit(); + document.$formname.submit(); return; } - ENDSCRIPT +} + +sub userlogdisplay_navlinks { + my ($curr,$more_records) = @_; + return unless(ref($curr) eq 'HASH'); + # Navigation Buttons + my $nav_links = '

'; + if (($curr->{'page'} > 1) || ($more_records)) { + if (($curr->{'page'} > 1) && ($curr->{'show'} !~ /\D/)) { + $nav_links .= ' '; + } + if ($more_records) { + $nav_links .= ''; } - } else { - $r->print(&mt('There are no records to display')); } - $r->print(''. - ''); - return; + $nav_links .= '

'; + return $nav_links; } sub role_display_filter { - my ($formname,$cdom,$cnum,$curr,$version) = @_; - my $context = 'course'; + my ($context,$formname,$cdom,$cnum,$curr,$version,$crstype) = @_; my $nolink = 1; my $output = ''; my $startform = @@ -4896,23 +8555,27 @@ sub role_display_filter { &Apache::lonhtmlcommon::date_setter($formname,'rolelog_end_date', $curr->{'rolelog_end_date'},undef, undef,undef,undef,undef,undef,undef,$nolink); - my %lt = &rolechg_contexts(); - $output .= ''. + my %lt = &rolechg_contexts($context,$crstype); + $output .= ''. + ''. ''. + ''. + '
'. - ''.&mt('Changes/page:').'
'. - &Apache::lonmeta::selectbox('show',$curr->{'show'},undef, + ''.&mt('Changes/page:').'
'. + &Apache::lonmeta::selectbox('show',$curr->{'show'},'',undef, (&mt('all'),5,10,20,50,100,1000,10000)). '
  '.&mt('Window during which changes occurred:').'
'.&mt('After:'). - ''.$startform.'
'.&mt('Before:').''. - $endform.'
  '.&mt('Window during which changes occurred:').'
'. + ''. + ''. + '
'.&mt('After:'). + ''.$startform.'
'.&mt('Before:').''.$endform.'
'. + '
  '.&mt('Role:').'
'. '
  '. + $output .= '  '. &mt('Context:').'
  
'. - ''. - &mt('[_1]Note:[_2] Only changes made from servers running LON-CAPA 2.6.99.0 or later are displayed.'); + my @possapprovals = ('any','none','domain','user'); + my %apptxt = &approval_types(); + $output .= ''. + '  '. + ''. + &mt('Approvals:').'
'; + + # Update Display button + $output .= '

' + .'' + .'

'; + + # Server version info + my $needsrev = '2.11.0'; + if ($context eq 'course') { + $needsrev = '2.7.0'; + } + + $output .= '

' + .&mt('Only changes made from servers running LON-CAPA [_1] or later are displayed.' + ,$needsrev); if ($version) { - $output .= ' '.&mt('This server is version [_3].','','',$version); } - $output .= '



'; + $output .= ' '.&mt('This LON-CAPA server is version [_1]',$version); + } + $output .= '


'; return $output; } sub rolechg_contexts { - my %lt = &Apache::lonlocal::texthash ( + my ($context,$crstype) = @_; + my %lt; + if ($context eq 'course') { + %lt = &Apache::lonlocal::texthash ( any => 'Any', - auto => 'Automated enrollment', + automated => 'Automated Enrollment', + chgtype => 'Enrollment Type/Lock Change', updatenow => 'Roster Update', createcourse => 'Course Creation', course => 'User Management in course', domain => 'User Management in domain', - selfenroll => 'Self-enrolled', + selfenroll => 'Self-enrolled', + requestcourses => 'Course Request', + ltienroll => 'Enrollment via LTI', ); + if ($crstype eq 'Community') { + $lt{'createcourse'} = &mt('Community Creation'); + $lt{'course'} = &mt('User Management in community'); + $lt{'requestcourses'} = &mt('Community Request'); + } + } elsif ($context eq 'domain') { + %lt = &Apache::lonlocal::texthash ( + any => 'Any', + domain => 'User Management in domain', + requestauthor => 'Authoring Request', + server => 'Command line script (DC role)', + domconfig => 'Self-enrolled', + ); + } else { + %lt = &Apache::lonlocal::texthash ( + any => 'Any', + domain => 'User Management in domain', + author => 'User Management by author', + coauthor => 'User Management by coauthor', + ); + } return %lt; } +sub approval_types { + return &Apache::lonlocal::texthash ( + any => 'Any', + none => 'No approval needed', + user => 'Role recipient approval', + domain => 'Domain coordinator approval', + ); +} + +sub print_helpdeskaccess_display { + my ($r,$permission,$brcrum) = @_; + my $formname = 'helpdeskaccess'; + my $helpitem = 'Course_Helpdesk_Access'; + push (@{$brcrum}, + {href => '/adm/createuser?action=helpdesk', + text => 'Helpdesk Access', + help => $helpitem}); + my $bread_crumbs_component = 'Helpdesk Staff Access'; + my $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $confname = $cdom.'-domainconfig'; + my $crstype = &Apache::loncommon::course_type(); + + my @accesstypes = ('all','dh','da','none'); + my ($numstatustypes,@jsarray); + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($cdom); + if (ref($types) eq 'ARRAY') { + if (@{$types} > 0) { + $numstatustypes = scalar(@{$types}); + push(@accesstypes,'status'); + @jsarray = ('bystatus'); + } + } + my %customroles = &get_domain_customroles($cdom,$confname); + my %domhelpdesk = &Apache::lonnet::get_active_domroles($cdom,['dh','da']); + if (keys(%domhelpdesk)) { + push(@accesstypes,('inc','exc')); + push(@jsarray,('notinc','notexc')); + } + push(@jsarray,'privs'); + my $hiddenstr = join("','",@jsarray); + my $rolestr = join("','",sort(keys(%customroles))); + + my $jscript; + my (%settings,%overridden); + if (keys(%customroles)) { + &get_adhocrole_settings($env{'request.course.id'},\@accesstypes, + $types,\%customroles,\%settings,\%overridden); + my %jsfull=(); + my %jslevels= ( + course => {}, + domain => {}, + system => {}, + ); + my %jslevelscurrent=( + course => {}, + domain => {}, + system => {}, + ); + my (%privs,%jsprivs); + &Apache::lonuserutils::custom_role_privs(\%privs,\%jsfull,\%jslevels,\%jslevelscurrent); + foreach my $priv (keys(%jsfull)) { + if ($jslevels{'course'}{$priv}) { + $jsprivs{$priv} = 1; + } + } + my (%elements,%stored); + foreach my $role (keys(%customroles)) { + $elements{$role.'_access'} = 'radio'; + $elements{$role.'_incrs'} = 'radio'; + if ($numstatustypes) { + $elements{$role.'_status'} = 'checkbox'; + } + if (keys(%domhelpdesk) > 0) { + $elements{$role.'_staff_inc'} = 'checkbox'; + $elements{$role.'_staff_exc'} = 'checkbox'; + } + $elements{$role.'_override'} = 'checkbox'; + if (ref($settings{$role}) eq 'HASH') { + if ($settings{$role}{'access'} ne '') { + my $curraccess = $settings{$role}{'access'}; + $stored{$role.'_access'} = $curraccess; + $stored{$role.'_incrs'} = 1; + if ($curraccess eq 'status') { + if (ref($settings{$role}{'status'}) eq 'ARRAY') { + $stored{$role.'_status'} = $settings{$role}{'status'}; + } + } elsif (($curraccess eq 'exc') || ($curraccess eq 'inc')) { + if (ref($settings{$role}{$curraccess}) eq 'ARRAY') { + $stored{$role.'_staff_'.$curraccess} = $settings{$role}{$curraccess}; + } + } + } else { + $stored{$role.'_incrs'} = 0; + } + $stored{$role.'_override'} = []; + if ($env{'course.'.$env{'request.course.id'}.'.internal.adhocpriv.'.$role}) { + if (ref($settings{$role}{'off'}) eq 'ARRAY') { + foreach my $priv (@{$settings{$role}{'off'}}) { + push(@{$stored{$role.'_override'}},$priv); + } + } + if (ref($settings{$role}{'on'}) eq 'ARRAY') { + foreach my $priv (@{$settings{$role}{'on'}}) { + unless (grep(/^$priv$/,@{$stored{$role.'_override'}})) { + push(@{$stored{$role.'_override'}},$priv); + } + } + } + } + } else { + $stored{$role.'_incrs'} = 0; + } + } + $jscript = &Apache::lonhtmlcommon::set_form_elements(\%elements,\%stored); + } + + my $js = <<"ENDJS"; + +ENDJS + + $args->{add_entries} = {onload => "javascript:setFormElements(document.$formname)"}; + + # print page header + $r->print(&header($js,$args)); + # print form header + $r->print('
'); + + if (keys(%customroles)) { + my %lt = &Apache::lonlocal::texthash( + 'aco' => 'As course owner you may override the defaults set in the domain for role usage and/or privileges.', + 'rou' => 'Role usage', + 'whi' => 'Which helpdesk personnel may use this role?', + 'udd' => 'Use domain default', + 'all' => 'All with domain helpdesk or helpdesk assistant role', + 'dh' => 'All with domain helpdesk role', + 'da' => 'All with domain helpdesk assistant role', + 'none' => 'None', + 'status' => 'Determined based on institutional status', + 'inc' => 'Include all, but exclude specific personnel', + 'exc' => 'Exclude all, but include specific personnel', + 'hel' => 'Helpdesk', + 'rpr' => 'Role privileges', + ); + $lt{'tfh'} = &mt("Custom [_1]ad hoc[_2] course roles available for use by the domain's helpdesk are as follows",'',''); + my %domconfig = &Apache::lonnet::get_dom('configuration',['helpsettings'],$cdom); + my (%domcurrent,%ordered,%description,%domusage,$disabled); + if (ref($domconfig{'helpsettings'}) eq 'HASH') { + if (ref($domconfig{'helpsettings'}{'adhoc'}) eq 'HASH') { + %domcurrent = %{$domconfig{'helpsettings'}{'adhoc'}}; + } + } + my $count = 0; + foreach my $role (sort(keys(%customroles))) { + my ($order,$desc,$access_in_dom); + if (ref($domcurrent{$role}) eq 'HASH') { + $order = $domcurrent{$role}{'order'}; + $desc = $domcurrent{$role}{'desc'}; + $access_in_dom = $domcurrent{$role}{'access'}; + } + if ($order eq '') { + $order = $count; + } + $ordered{$order} = $role; + if ($desc ne '') { + $description{$role} = $desc; + } else { + $description{$role}= $role; + } + $count++; + } + %domusage = &domain_adhoc_access(\%customroles,\%domcurrent,\@accesstypes,$usertypes,$othertitle); + my @roles_by_num = (); + foreach my $item (sort {$a <=> $b } (keys(%ordered))) { + push(@roles_by_num,$ordered{$item}); + } + $r->print('

'.$lt{'tfh'}.': '.join(', ',map { $description{$_}; } @roles_by_num).'.'); + if ($permission->{'owner'}) { + $r->print('
'.$lt{'aco'}.'

'); + $r->print(''. + ''); + } else { + if ($env{'course.'.$env{'request.course.id'}.'.internal.courseowner'}) { + my ($ownername,$ownerdom) = split(/:/,$env{'course.'.$env{'request.course.id'}.'.internal.courseowner'}); + $r->print('
'.&mt('The course owner -- [_1] -- can override the default access and/or privileges for these ad hoc roles.', + &Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($ownername,$ownerdom),$ownername,$ownerdom))); + } + $disabled = ' disabled="disabled"'; + } + $r->print('

'); + + $r->print('
    '); + my $count = 0; + my %visibility; + foreach my $role (@roles_by_num) { + my $id; + if ($count == 0) { + $id=' id="LC_current_minitab"'; + $visibility{$role} = ' style="display:block"'; + } else { + $visibility{$role} = ' style="display:none"'; + } + $count ++; + $r->print(''.$description{$role}.''); + } + $r->print('
'); + + foreach my $role (@roles_by_num) { + my %usecheck = ( + all => ' checked="checked"', + ); + my %displaydiv = ( + status => 'none', + inc => 'none', + exc => 'none', + priv => 'block', + ); + my (%selected,$overridden,$incrscheck,$indomcheck,$indomvis,$incrsvis); + if (ref($settings{$role}) eq 'HASH') { + if ($settings{$role}{'access'} ne '') { + $indomvis = ' style="display:none"'; + $incrsvis = ' style="display:block"'; + $incrscheck = ' checked="checked"'; + if ($settings{$role}{'access'} ne 'all') { + $usecheck{$settings{$role}{'access'}} = $usecheck{'all'}; + delete($usecheck{'all'}); + if ($settings{$role}{'access'} eq 'status') { + my $access = 'status'; + $displaydiv{$access} = 'inline'; + if (ref($settings{$role}{$access}) eq 'ARRAY') { + $selected{$access} = $settings{$role}{$access}; + } + } elsif ($settings{$role}{'access'} =~ /^(inc|exc)$/) { + my $access = $1; + $displaydiv{$access} = 'inline'; + if (ref($settings{$role}{$access}) eq 'ARRAY') { + $selected{$access} = $settings{$role}{$access}; + } + } elsif ($settings{$role}{'access'} eq 'none') { + $displaydiv{'priv'} = 'none'; + } + } + } else { + $indomcheck = ' checked="checked"'; + $indomvis = ' style="display:block"'; + $incrsvis = ' style="display:none"'; + } + } else { + $indomcheck = ' checked="checked"'; + $indomvis = ' style="display:block"'; + $incrsvis = ' style="display:none"'; + } + $r->print('
'. + '
'.$lt{'rou'}.''. + '

'.$lt{'whi'}.' '. + ''. + ''.(' 'x2). + '

'. + '
'. + ''.$domusage{$role}.'
'. + '
'); + foreach my $access (@accesstypes) { + $r->print('

'); + if ($access eq 'status') { + $r->print('

'. + &Apache::lonuserutils::adhoc_status_types($cdom,undef,$role,$selected{$access}, + $othertitle,$usertypes,$types,$disabled). + '
'); + } elsif (($access eq 'inc') && (keys(%domhelpdesk) > 0)) { + $r->print('
'. + &Apache::lonuserutils::adhoc_staff($access,undef,$role,$selected{$access}, + \%domhelpdesk,$disabled). + '
'); + } elsif (($access eq 'exc') && (keys(%domhelpdesk) > 0)) { + $r->print('
'. + &Apache::lonuserutils::adhoc_staff($access,undef,$role,$selected{$access}, + \%domhelpdesk,$disabled). + '
'); + } + $r->print('

'); + } + $r->print('
'); + my %full=(); + my %levels= ( + course => {}, + domain => {}, + system => {}, + ); + my %levelscurrent=( + course => {}, + domain => {}, + system => {}, + ); + &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent); + $r->print('
'. + ''.$lt{'rpr'}.''. + &role_priv_table($role,$permission,$crstype,\%full,\%levels,\%levelscurrent,$overridden{$role}). + '
'); + } + if ($permission->{'owner'}) { + $r->print('

'); + } + } else { + $r->print(&mt('Helpdesk roles have not yet been created in this domain.')); + } + # Form Footer + $r->print('' + .'
'); + return; +} + +sub print_queued_roles { + my ($r,$context,$permission,$brcrum) = @_; + push (@{$brcrum}, + {href => '/adm/createuser?action=rolerequests', + text => 'Role Requests (other domains)', + help => ''}); + my $bread_crumbs_component = 'Role Requests'; + my $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + # print page header + $r->print(&header('',$args)); + my ($dom,$cnum); + $dom = $env{'request.role.domain'}; + if ($context eq 'course') { + if ($env{'request.course.id'}) { + if (&Apache::loncommon::course_type() eq 'Community') { + $context = 'community'; + } + $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + } + } elsif ($context eq 'author') { + $cnum = $env{'user.name'}; + } + $r->print(&Apache::loncoursequeueadmin::display_queued_requests('othdomqueue',$dom,$cnum,$context)); + return; +} + +sub print_pendingroles { + my ($r,$context,$permission,$brcrum) = @_; + push (@{$brcrum}, + {href => '/adm/createuser?action=queuedroles', + text => 'Queued Role Assignments (users in this domain)', + help => ''}); + my $bread_crumbs_component = 'Queued Role Assignments'; + my $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + # print page header + $r->print(&header('',$args)); + $r->print(&Apache::loncoursequeueadmin::display_queued_requests('othdomaction',$env{'request.role.domain'},'','domain')); + return; +} + +sub process_pendingroles { + my ($r,$context,$permission,$brcrum) = @_; + push (@{$brcrum}, + {href => '/adm/createuser?action=queuedroles', + text => 'Queued Role Assignments (users in this domain)', + help => ''}, + {href => '/adm/createuser?action=processrolereq', + text => 'Process Queue', + help => ''}); + my $bread_crumbs_component = 'Queued Role Assignments'; + my $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + # print page header + $r->print(&header('',$args)); + $r->print(&Apache::loncoursequeueadmin::update_request_queue('othdombydc', + $env{'request.role.domain'})); + return; +} + +sub domain_adhoc_access { + my ($roles,$domcurrent,$accesstypes,$usertypes,$othertitle) = @_; + my %domusage; + return unless ((ref($roles) eq 'HASH') && (ref($domcurrent) eq 'HASH') && (ref($accesstypes) eq 'ARRAY')); + foreach my $role (keys(%{$roles})) { + if (ref($domcurrent->{$role}) eq 'HASH') { + my $access = $domcurrent->{$role}{'access'}; + if (($access eq '') || (!grep(/^\Q$access\E$/,@{$accesstypes}))) { + $access = 'all'; + $domusage{$role} = &mt('Any user in domain with active [_1] or [_2] role',&Apache::lonnet::plaintext('dh'), + &Apache::lonnet::plaintext('da')); + } elsif ($access eq 'status') { + if (ref($domcurrent->{$role}{$access}) eq 'ARRAY') { + my @shown; + foreach my $type (@{$domcurrent->{$role}{$access}}) { + unless ($type eq 'default') { + if ($usertypes->{$type}) { + push(@shown,$usertypes->{$type}); + } + } + } + if (grep(/^default$/,@{$domcurrent->{$role}{$access}})) { + push(@shown,$othertitle); + } + if (@shown) { + my $shownstatus = join(' '.&mt('or').' ',@shown); + $domusage{$role} = &mt('Any user in domain with active [_1] or [_2] role, and institutional status: [_3]', + &Apache::lonnet::plaintext('dh'),&Apache::lonnet::plaintext('da'),$shownstatus); + } else { + $domusage{$role} = &mt('No one in the domain'); + } + } + } elsif ($access eq 'inc') { + my @dominc = (); + if (ref($domcurrent->{$role}{'inc'}) eq 'ARRAY') { + foreach my $user (@{$domcurrent->{$role}{'inc'}}) { + my ($uname,$udom) = split(/:/,$user); + push(@dominc,&Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom)); + } + my $showninc = join(', ',@dominc); + if ($showninc ne '') { + $domusage{$role} = &mt('Include any user in domain with active [_1] or [_2] role, except: [_3]', + &Apache::lonnet::plaintext('dh'),&Apache::lonnet::plaintext('da'),$showninc); + } else { + $domusage{$role} = &mt('Any user in domain with active [_1] or [_2] role', + &Apache::lonnet::plaintext('dh'),&Apache::lonnet::plaintext('da')); + } + } + } elsif ($access eq 'exc') { + my @domexc = (); + if (ref($domcurrent->{$role}{'exc'}) eq 'ARRAY') { + foreach my $user (@{$domcurrent->{$role}{'exc'}}) { + my ($uname,$udom) = split(/:/,$user); + push(@domexc,&Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom),$uname,$udom)); + } + } + my $shownexc = join(', ',@domexc); + if ($shownexc ne '') { + $domusage{$role} = &mt('Only the following in the domain with active [_1] or [_2] role: [_3]', + &Apache::lonnet::plaintext('dh'),&Apache::lonnet::plaintext('da'),$shownexc); + } else { + $domusage{$role} = &mt('No one in the domain'); + } + } elsif ($access eq 'none') { + $domusage{$role} = &mt('No one in the domain'); + } elsif ($access eq 'dh') { + $domusage{$role} = &mt('Any user in domain with active [_1] role',&Apache::lonnet::plaintext('dh')); + } elsif ($access eq 'da') { + $domusage{$role} = &mt('Any user in domain with active [_1] role',&Apache::lonnet::plaintext('da')); + } elsif ($access eq 'all') { + $domusage{$role} = &mt('Any user in domain with active [_1] or [_2] role', + &Apache::lonnet::plaintext('dh'),&Apache::lonnet::plaintext('da')); + } + } else { + $domusage{$role} = &mt('Any user in domain with active [_1] or [_2] role', + &Apache::lonnet::plaintext('dh'),&Apache::lonnet::plaintext('da')); + } + } + return %domusage; +} + +sub get_domain_customroles { + my ($cdom,$confname) = @_; + my %existing=&Apache::lonnet::dump('roles',$cdom,$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; + } + } + return %customroles; +} + +sub role_priv_table { + my ($role,$permission,$crstype,$full,$levels,$levelscurrent,$overridden) = @_; + return unless ((ref($full) eq 'HASH') && (ref($levels) eq 'HASH') && + (ref($levelscurrent) eq 'HASH')); + my %lt=&Apache::lonlocal::texthash ( + 'crl' => 'Course Level Privilege', + 'def' => 'Domain Defaults', + 'ove' => 'Override in Course', + 'ine' => 'In effect', + 'dis' => 'Disabled', + 'ena' => 'Enabled', + ); + if ($crstype eq 'Community') { + $lt{'ove'} = 'Override in Community', + } + my @status = ('Disabled','Enabled'); + my (%on,%off); + if (ref($overridden) eq 'HASH') { + if (ref($overridden->{'on'}) eq 'ARRAY') { + map { $on{$_} = 1; } (@{$overridden->{'on'}}); + } + if (ref($overridden->{'off'}) eq 'ARRAY') { + map { $off{$_} = 1; } (@{$overridden->{'off'}}); + } + } + my $output=&Apache::loncommon::start_data_table(). + &Apache::loncommon::start_data_table_header_row(). + ''.$lt{'crl'}.''.$lt{'def'}.''.$lt{'ove'}. + ''.$lt{'ine'}.''. + &Apache::loncommon::end_data_table_header_row(); + foreach my $priv (sort(keys(%{$full}))) { + next unless ($levels->{'course'}{$priv}); + my $privtext = &Apache::lonnet::plaintext($priv,$crstype); + my ($default,$ineffect); + if ($levelscurrent->{'course'}{$priv}) { + $default = ''.$lt{'ena'}.''; + $ineffect = $default; + } + my ($customstatus,$checked); + $output .= &Apache::loncommon::start_data_table_row(). + ''.$privtext.''. + ''.$default.''; + if (($levelscurrent->{'course'}{$priv}) && ($off{$priv})) { + if ($permission->{'owner'}) { + $checked = ' checked="checked"'; + } + $customstatus = ''.$lt{'dis'}.''; + $ineffect = $customstatus; + } elsif ((!$levelscurrent->{'course'}{$priv}) && ($on{$priv})) { + if ($permission->{'owner'}) { + $checked = ' checked="checked"'; + } + $customstatus = ''.$lt{'ena'}.''; + $ineffect = $customstatus; + } + if ($permission->{'owner'}) { + $output .= ''; + } else { + $output .= $customstatus; + } + $output .= ''.$ineffect.''. + &Apache::loncommon::end_data_table_row(); + } + $output .= &Apache::loncommon::end_data_table(); + return $output; +} + +sub get_adhocrole_settings { + my ($cid,$accesstypes,$types,$customroles,$settings,$overridden) = @_; + return unless ((ref($accesstypes) eq 'ARRAY') && (ref($customroles) eq 'HASH') && + (ref($settings) eq 'HASH') && (ref($overridden) eq 'HASH')); + foreach my $role (split(/,/,$env{'course.'.$cid.'.internal.adhocaccess'})) { + my ($curraccess,$rest) = split(/=/,$env{'course.'.$cid.'.internal.adhoc.'.$role}); + if (($curraccess ne '') && (grep(/^\Q$curraccess\E$/,@{$accesstypes}))) { + $settings->{$role}{'access'} = $curraccess; + if (($curraccess eq 'status') && (ref($types) eq 'ARRAY')) { + my @status = split(/,/,$rest); + my @currstatus; + foreach my $type (@status) { + if ($type eq 'default') { + push(@currstatus,$type); + } elsif (grep(/^\Q$type\E$/,@{$types})) { + push(@currstatus,$type); + } + } + if (@currstatus) { + $settings->{$role}{$curraccess} = \@currstatus; + } elsif (($curraccess eq 'exc') || ($curraccess eq 'inc')) { + my @personnel = split(/,/,$rest); + $settings->{$role}{$curraccess} = \@personnel; + } + } + } + } + foreach my $role (keys(%{$customroles})) { + if ($env{'course.'.$cid.'.internal.adhocpriv.'.$role}) { + my %currentprivs; + if (ref($customroles->{$role}) eq 'HASH') { + if (exists($customroles->{$role}{'course'})) { + my %full=(); + my %levels= ( + course => {}, + domain => {}, + system => {}, + ); + my %levelscurrent=( + course => {}, + domain => {}, + system => {}, + ); + &Apache::lonuserutils::custom_role_privs($customroles->{$role},\%full,\%levels,\%levelscurrent); + %currentprivs = %{$levelscurrent{'course'}}; + } + } + foreach my $item (split(/,/,$env{'course.'.$cid.'.internal.adhocpriv.'.$role})) { + next if ($item eq ''); + my ($rule,$rest) = split(/=/,$item); + next unless (($rule eq 'off') || ($rule eq 'on')); + foreach my $priv (split(/:/,$rest)) { + if ($priv ne '') { + if ($rule eq 'off') { + push(@{$overridden->{$role}{'off'}},$priv); + if ($currentprivs{$priv}) { + push(@{$settings->{$role}{'off'}},$priv); + } + } else { + push(@{$overridden->{$role}{'on'}},$priv); + unless ($currentprivs{$priv}) { + push(@{$settings->{$role}{'on'}},$priv); + } + } + } + } + } + } + } + return; +} + +sub update_helpdeskaccess { + my ($r,$permission,$brcrum) = @_; + my $helpitem = 'Course_Helpdesk_Access'; + push (@{$brcrum}, + {href => '/adm/createuser?action=helpdesk', + text => 'Helpdesk Access', + help => $helpitem}, + {href => '/adm/createuser?action=helpdesk', + text => 'Result', + help => $helpitem} + ); + my $bread_crumbs_component = 'Helpdesk Staff Access'; + my $args = { bread_crumbs => $brcrum, + bread_crumbs_component => $bread_crumbs_component}; + + # print page header + $r->print(&header('',$args)); + unless ((ref($permission) eq 'HASH') && ($permission->{'owner'})) { + $r->print('

'.&mt('You do not have permission to change helpdesk access.').'

'); + return; + } + my @accesstypes = ('all','dh','da','none','status','inc','exc'); + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $confname = $cdom.'-domainconfig'; + my ($othertitle,$usertypes,$types) = &Apache::loncommon::sorted_inst_types($cdom); + my $crstype = &Apache::loncommon::course_type(); + my %customroles = &get_domain_customroles($cdom,$confname); + my (%settings,%overridden); + &get_adhocrole_settings($env{'request.course.id'},\@accesstypes, + $types,\%customroles,\%settings,\%overridden); + my %domhelpdesk = &Apache::lonnet::get_active_domroles($cdom,['dh','da']); + my (%changed,%storehash,@todelete); + + if (keys(%customroles)) { + my (%newsettings,@incrs); + foreach my $role (keys(%customroles)) { + $newsettings{$role} = { + access => '', + status => '', + exc => '', + inc => '', + on => '', + off => '', + }; + my %current; + if (ref($settings{$role}) eq 'HASH') { + %current = %{$settings{$role}}; + } + if (ref($overridden{$role}) eq 'HASH') { + $current{'overridden'} = $overridden{$role}; + } + if ($env{'form.'.$role.'_incrs'}) { + my $access = $env{'form.'.$role.'_access'}; + if (grep(/^\Q$access\E$/,@accesstypes)) { + push(@incrs,$role); + unless ($current{'access'} eq $access) { + $changed{$role}{'access'} = 1; + $storehash{'internal.adhoc.'.$role} = $access; + } + if ($access eq 'status') { + my @statuses = &Apache::loncommon::get_env_multiple('form.'.$role.'_status'); + my @stored; + my @shownstatus; + if (ref($types) eq 'ARRAY') { + foreach my $type (sort(@statuses)) { + if ($type eq 'default') { + push(@stored,$type); + } elsif (grep(/^\Q$type\E$/,@{$types})) { + push(@stored,$type); + push(@shownstatus,$usertypes->{$type}); + } + } + if (grep(/^default$/,@statuses)) { + push(@shownstatus,$othertitle); + } + $storehash{'internal.adhoc.'.$role} .= '='.join(',',@stored); + } + $newsettings{$role}{'status'} = join(' '.&mt('or').' ',@shownstatus); + if (ref($current{'status'}) eq 'ARRAY') { + my @diffs = &Apache::loncommon::compare_arrays(\@stored,$current{'status'}); + if (@diffs) { + $changed{$role}{'status'} = 1; + } + } elsif (@stored) { + $changed{$role}{'status'} = 1; + } + } elsif (($access eq 'inc') || ($access eq 'exc')) { + my @personnel = &Apache::loncommon::get_env_multiple('form.'.$role.'_staff_'.$access); + my @newspecstaff; + my @stored; + my @currstaff; + foreach my $person (sort(@personnel)) { + if ($domhelpdesk{$person}) { + push(@stored,$person); + } + } + if (ref($current{$access}) eq 'ARRAY') { + my @diffs = &Apache::loncommon::compare_arrays(\@stored,$current{$access}); + if (@diffs) { + $changed{$role}{$access} = 1; + } + } elsif (@stored) { + $changed{$role}{$access} = 1; + } + $storehash{'internal.adhoc.'.$role} .= '='.join(',',@stored); + foreach my $person (@stored) { + my ($uname,$udom) = split(/:/,$person); + push(@newspecstaff,&Apache::loncommon::aboutmewrapper(&Apache::loncommon::plainname($uname,$udom,'lastname'),$uname,$udom)); + } + $newsettings{$role}{$access} = join(', ',sort(@newspecstaff)); + } + $newsettings{$role}{'access'} = $access; + } + } else { + if (($current{'access'} ne '') && (grep(/^\Q$current{'access'}\E$/,@accesstypes))) { + $changed{$role}{'access'} = 1; + $newsettings{$role} = {}; + push(@todelete,'internal.adhoc.'.$role); + } + } + if (($env{'form.'.$role.'_incrs'}) && ($env{'form.'.$role.'_access'} eq 'none')) { + if (ref($current{'overridden'}) eq 'HASH') { + push(@todelete,'internal.adhocpriv.'.$role); + } + } else { + my %full=(); + my %levels= ( + course => {}, + domain => {}, + system => {}, + ); + my %levelscurrent=( + course => {}, + domain => {}, + system => {}, + ); + &Apache::lonuserutils::custom_role_privs($customroles{$role},\%full,\%levels,\%levelscurrent); + my (@updatedon,@updatedoff,@override); + @override = &Apache::loncommon::get_env_multiple('form.'.$role.'_override'); + if (@override) { + foreach my $priv (sort(keys(%full))) { + next unless ($levels{'course'}{$priv}); + if (grep(/^\Q$priv\E$/,@override)) { + if ($levelscurrent{'course'}{$priv}) { + push(@updatedoff,$priv); + } else { + push(@updatedon,$priv); + } + } + } + } + if (@updatedon) { + $newsettings{$role}{'on'} = join('
  • ', map { &Apache::lonnet::plaintext($_,$crstype) } (@updatedon)); + } + if (@updatedoff) { + $newsettings{$role}{'off'} = join('
  • ', map { &Apache::lonnet::plaintext($_,$crstype) } (@updatedoff)); + } + if (ref($current{'overridden'}) eq 'HASH') { + if (ref($current{'overridden'}{'on'}) eq 'ARRAY') { + if (@updatedon) { + my @diffs = &Apache::loncommon::compare_arrays(\@updatedon,$current{'overridden'}{'on'}); + if (@diffs) { + $changed{$role}{'on'} = 1; + } + } else { + $changed{$role}{'on'} = 1; + } + } elsif (@updatedon) { + $changed{$role}{'on'} = 1; + } + if (ref($current{'overridden'}{'off'}) eq 'ARRAY') { + if (@updatedoff) { + my @diffs = &Apache::loncommon::compare_arrays(\@updatedoff,$current{'overridden'}{'off'}); + if (@diffs) { + $changed{$role}{'off'} = 1; + } + } else { + $changed{$role}{'off'} = 1; + } + } elsif (@updatedoff) { + $changed{$role}{'off'} = 1; + } + } else { + if (@updatedon) { + $changed{$role}{'on'} = 1; + } + if (@updatedoff) { + $changed{$role}{'off'} = 1; + } + } + if (ref($changed{$role}) eq 'HASH') { + if (($changed{$role}{'on'} || $changed{$role}{'off'})) { + my $newpriv; + if (@updatedon) { + $newpriv = 'on='.join(':',@updatedon); + } + if (@updatedoff) { + $newpriv .= ($newpriv ? ',' : '' ).'off='.join(':',@updatedoff); + } + if ($newpriv eq '') { + push(@todelete,'internal.adhocpriv.'.$role); + } else { + $storehash{'internal.adhocpriv.'.$role} = $newpriv; + } + } + } + } + } + if (@incrs) { + $storehash{'internal.adhocaccess'} = join(',',@incrs); + } elsif (@todelete) { + push(@todelete,'internal.adhocaccess'); + } + if (keys(%changed)) { + my ($putres,$delres); + if (keys(%storehash)) { + $putres = &Apache::lonnet::put('environment',\%storehash,$cdom,$cnum); + my %newenvhash; + foreach my $key (keys(%storehash)) { + $newenvhash{'course.'.$env{'request.course.id'}.'.'.$key} = $storehash{$key}; + } + &Apache::lonnet::appenv(\%newenvhash); + } + if (@todelete) { + $delres = &Apache::lonnet::del('environment',\@todelete,$cdom,$cnum); + foreach my $key (@todelete) { + &Apache::lonnet::delenv('course.'.$env{'request.course.id'}.'.'.$key); + } + } + if (($putres eq 'ok') || ($delres eq 'ok')) { + my %domconfig = &Apache::lonnet::get_dom('configuration',['helpsettings'],$cdom); + my (%domcurrent,%ordered,%description,%domusage); + if (ref($domconfig{'helpsettings'}) eq 'HASH') { + if (ref($domconfig{'helpsettings'}{'adhoc'}) eq 'HASH') { + %domcurrent = %{$domconfig{'helpsettings'}{'adhoc'}}; + } + } + my $count = 0; + foreach my $role (sort(keys(%customroles))) { + my ($order,$desc); + if (ref($domcurrent{$role}) eq 'HASH') { + $order = $domcurrent{$role}{'order'}; + $desc = $domcurrent{$role}{'desc'}; + } + if ($order eq '') { + $order = $count; + } + $ordered{$order} = $role; + if ($desc ne '') { + $description{$role} = $desc; + } else { + $description{$role}= $role; + } + $count++; + } + my @roles_by_num = (); + foreach my $item (sort {$a <=> $b } (keys(%ordered))) { + push(@roles_by_num,$ordered{$item}); + } + %domusage = &domain_adhoc_access(\%changed,\%domcurrent,\@accesstypes,$usertypes,$othertitle); + $r->print(&mt('Helpdesk access settings have been changed as follows').'
    '); + $r->print('
      '); + foreach my $role (@roles_by_num) { + next unless (ref($changed{$role}) eq 'HASH'); + $r->print('
    • '.&mt('Ad hoc role').': '.$description{$role}.''. + '
        '); + if ($changed{$role}{'access'} || $changed{$role}{'status'} || $changed{$role}{'inc'} || $changed{$role}{'exc'}) { + $r->print('
      • '); + if ($env{'form.'.$role.'_incrs'}) { + if ($newsettings{$role}{'access'} eq 'all') { + $r->print(&mt('All helpdesk staff can access '.lc($crstype).' with this role.')); + } elsif ($newsettings{$role}{'access'} eq 'dh') { + $r->print(&mt('Helpdesk staff can use this role if they have an active [_1] role', + &Apache::lonnet::plaintext('dh'))); + } elsif ($newsettings{$role}{'access'} eq 'da') { + $r->print(&mt('Helpdesk staff can use this role if they have an active [_1] role', + &Apache::lonnet::plaintext('da'))); + } elsif ($newsettings{$role}{'access'} eq 'none') { + $r->print(&mt('No helpdesk staff can access '.lc($crstype).' with this role.')); + } elsif ($newsettings{$role}{'access'} eq 'status') { + if ($newsettings{$role}{'status'}) { + my ($access,$rest) = split(/=/,$storehash{'internal.adhoc.'.$role}); + if (split(/,/,$rest) > 1) { + $r->print(&mt('Helpdesk staff can use this role if their institutional type is one of: [_1].', + $newsettings{$role}{'status'})); + } else { + $r->print(&mt('Helpdesk staff can use this role if their institutional type is: [_1].', + $newsettings{$role}{'status'})); + } + } else { + $r->print(&mt('No helpdesk staff can access '.lc($crstype).' with this role.')); + } + } elsif ($newsettings{$role}{'access'} eq 'exc') { + if ($newsettings{$role}{'exc'}) { + $r->print(&mt('Helpdesk staff who can use this role are as follows:').' '.$newsettings{$role}{'exc'}.'.'); + } else { + $r->print(&mt('No helpdesk staff can access '.lc($crstype).' with this role.')); + } + } elsif ($newsettings{$role}{'access'} eq 'inc') { + if ($newsettings{$role}{'inc'}) { + $r->print(&mt('All helpdesk staff may use this role except the following:').' '.$newsettings{$role}{'inc'}.'.'); + } else { + $r->print(&mt('All helpdesk staff may use this role.')); + } + } + } else { + $r->print(&mt('Default access set in the domain now applies.').'
        '. + ''.$domusage{$role}.''); + } + $r->print('
      • '); + } + unless ($newsettings{$role}{'access'} eq 'none') { + if ($changed{$role}{'off'}) { + if ($newsettings{$role}{'off'}) { + $r->print('
      • '.&mt('Privileges which are available by default for this ad hoc role, but are disabled for this specific '.lc($crstype).':'). + '
        • '.$newsettings{$role}{'off'}.'
      • '); + } else { + $r->print('
      • '.&mt('All privileges available by default for this ad hoc role are enabled.').'
      • '); + } + } + if ($changed{$role}{'on'}) { + if ($newsettings{$role}{'on'}) { + $r->print('
      • '.&mt('Privileges which are not available by default for this ad hoc role, but are enabled for this specific '.lc($crstype).':'). + '
        • '.$newsettings{$role}{'on'}.'
      • '); + } else { + $r->print('
      • '.&mt('None of the privileges unavailable by default for this ad hoc role are enabled.').'
      • '); + } + } + } + $r->print('
    • '); + } + $r->print('
    '); + } + } else { + $r->print(&mt('No changes made to helpdesk access settings.')); + } + } + return; +} + #-------------------------------------------------- functions for &phase_two sub user_search_result { my ($context,$srch) = @_; @@ -4999,13 +9779,29 @@ sub user_search_result { } } if ($response ne '') { - $response = ''.$response.''; + $response = ''.$response.'
    '; } if ($srch->{'srchin'} eq 'instd') { - my $instd_chk = &directorysrch_check($srch); + my $instd_chk = &instdirectorysrch_check($srch); if ($instd_chk ne 'ok') { - $response = ''.$instd_chk.''. - '
    '.&mt('You may want to search in the LON-CAPA domain instead of the institutional directory.').'

    '; + my $domd_chk = &domdirectorysrch_check($srch); + $response .= ''.$instd_chk.'
    '; + if ($domd_chk eq 'ok') { + $response .= &mt('You may want to search in the LON-CAPA domain instead of in the institutional directory.'); + } + $response .= '
    '; + } + } else { + unless (($context eq 'requestcrs') && ($srch->{'srchtype'} eq 'exact')) { + my $domd_chk = &domdirectorysrch_check($srch); + if (($domd_chk ne 'ok') && ($env{'form.action'} ne 'accesslogs')) { + my $instd_chk = &instdirectorysrch_check($srch); + $response .= ''.$domd_chk.'
    '; + if ($instd_chk eq 'ok') { + $response .= &mt('You may want to search in the institutional directory instead of in the LON-CAPA domain.'); + } + $response .= '
    '; + } } } if ($response ne '') { @@ -5035,6 +9831,18 @@ sub user_search_result { &build_search_response($context,$srch,%srch_results); } else { $currstate = 'modify'; + if ($env{'form.action'} eq 'accesslogs') { + $currstate = 'activity'; + } + my $uname = $srch->{'srchterm'}; + my $udom = $srch->{'srchdomain'}; + $srch_results{$uname.':'.$udom} = + { &Apache::lonnet::get('environment', + ['firstname', + 'lastname', + 'permanentemail'], + $udom,$uname) + }; } } else { %srch_results = &Apache::lonnet::usersearch($srch); @@ -5091,8 +9899,8 @@ sub user_search_result { $response = ''. &mt('Institutional directory search is not available in domain: [_1]',$showdom). '
    '. - &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.'). - '

    '; + &mt('You may want to search in the LON-CAPA domain instead of in the institutional directory.'). + '
    '; } } } else { @@ -5160,18 +9968,38 @@ sub user_search_result { ($currstate,$response,$forcenewuser) = &build_search_response($context,$srch,%srch_results); } else { - my $showdom = &display_domain_info($srch->{'srchdomain'}); $response = ''. + my $showdom = &display_domain_info($srch->{'srchdomain'}); + $response = ''. &mt('Institutional directory search is not available in domain: [_1]',$showdom). '
    '. - &mt('You may want to search in the LON-CAPA domain instead of the institutional directory.'). - '

    '; + &mt('You may want to search in the LON-CAPA domain instead of in the institutional directory.'). + '
    '; } } } return ($currstate,$response,$forcenewuser,\%srch_results); } -sub directorysrch_check { +sub domdirectorysrch_check { + my ($srch) = @_; + my $response; + my %dom_inst_srch = &Apache::lonnet::get_dom('configuration', + ['directorysrch'],$srch->{'srchdomain'}); + my $showdom = &display_domain_info($srch->{'srchdomain'}); + if (ref($dom_inst_srch{'directorysrch'}) eq 'HASH') { + if ($dom_inst_srch{'directorysrch'}{'lcavailable'} eq '0') { + return &mt('LON-CAPA directory search is not available in domain: [_1]',$showdom); + } + if ($dom_inst_srch{'directorysrch'}{'lclocalonly'}) { + if ($env{'request.role.domain'} ne $srch->{'srchdomain'}) { + return &mt('LON-CAPA directory search in domain: [_1] is only allowed for users with a current role in the domain.',$showdom); + } + } + } + return 'ok'; +} + +sub instdirectorysrch_check { my ($srch) = @_; my $can_search = 0; my $response; @@ -5271,12 +10099,12 @@ sub build_search_response { my ($context,$srch,%srch_results) = @_; my ($currstate,$response,$forcenewuser); my %names = ( - 'uname' => 'username', - 'lastname' => 'last name', + 'uname' => 'username', + 'lastname' => 'last name', 'lastfirst' => 'last name, first name', - 'crs' => 'this course', - 'dom' => 'LON-CAPA domain: ', - 'instd' => 'the institutional directory for domain: ', + 'crs' => 'this course', + 'dom' => 'LON-CAPA domain', + 'instd' => 'the institutional directory for domain', ); my %single = ( @@ -5293,21 +10121,31 @@ sub build_search_response { $currstate = 'select'; } else { if (keys(%srch_results) == 1) { - $currstate = 'modify'; + if ($env{'form.action'} eq 'accesslogs') { + $currstate = 'activity'; + } else { + $currstate = 'modify'; + } $response = &mt("$single{$srch->{'srchtype'}} was found for the $names{$srch->{'srchby'}} ([_1]) in $names{$srch->{'srchin'}}.",$srch->{'srchterm'}); if ($srch->{'srchin'} eq 'dom' || $srch->{'srchin'} eq 'instd') { - $response .= &display_domain_info($srch->{'srchdomain'}); + $response .= ': '.&display_domain_info($srch->{'srchdomain'}); } - } else { - $response = ''.&mt("$nomatch{$srch->{'srchtype'}} found for the $names{$srch->{'srchby'}} ([_1]) in $names{$srch->{'srchin'}}",$srch->{'srchterm'}); + } else { # Search has nothing found. Prepare message to user. + $response = ''; if ($srch->{'srchin'} eq 'dom' || $srch->{'srchin'} eq 'instd') { - $response .= &display_domain_info($srch->{'srchdomain'}); + $response .= &mt("$nomatch{$srch->{'srchtype'}} found for the $names{$srch->{'srchby'}} [_1] in $names{$srch->{'srchin'}}: [_2]", + ''.$srch->{'srchterm'}.'', + &display_domain_info($srch->{'srchdomain'})); + } else { + $response .= &mt("$nomatch{$srch->{'srchtype'}} found for the $names{$srch->{'srchby'}} [_1] in $names{$srch->{'srchin'}}.", + ''.$srch->{'srchterm'}.''); } $response .= ''; + if ($srch->{'srchin'} ne 'alc') { $forcenewuser = 1; my $cansrchinst = 0; - if ($srch->{'srchdomain'}) { + if (($srch->{'srchdomain'}) && ($env{'form.action'} ne 'accesslogs')) { my %domconfig = &Apache::lonnet::get_dom('configuration',['directorysrch'],$srch->{'srchdomain'}); if (ref($domconfig{'directorysrch'}) eq 'HASH') { if ($domconfig{'directorysrch'}{'available'}) { @@ -5326,17 +10164,28 @@ sub build_search_response { $response .= '
    '.&mt('You may want to broaden your search to the selected LON-CAPA domain.'); } } - if (!($srch->{'srchby'} eq 'uname' && $srch->{'srchin'} eq 'dom' && $srch->{'srchtype'} eq 'exact' && $srch->{'srchdomain'} eq $env{'request.role.domain'})) { + my $createdom = $env{'request.role.domain'}; + if ($context eq 'requestcrs') { + if ($env{'form.coursedom'} ne '') { + $createdom = $env{'form.coursedom'}; + } + } + unless (($env{'form.action'} eq 'accesslogs') || (($srch->{'srchby'} eq 'uname') && ($srch->{'srchin'} eq 'dom') && + ($srch->{'srchtype'} eq 'exact') && ($srch->{'srchdomain'} eq $createdom))) { my $cancreate = - &Apache::lonuserutils::can_create_user($env{'request.role.domain'},$context); + &Apache::lonuserutils::can_create_user($createdom,$context); + my $targetdom = ''.$createdom.''; if ($cancreate) { - my $showdom = &display_domain_info($env{'request.role.domain'}); + my $showdom = &display_domain_info($createdom); $response .= '

    ' .''.&mt('To add a new user:').'' - .'
    ' - .&mt("(You can only create new users in your current role's domain - [_1])" - ,''.$env{'request.role.domain'}.'') - .'
    • ' + .'
      '; + if ($context eq 'requestcrs') { + $response .= &mt("(You can only define new users in the new course's domain - [_1])",$targetdom); + } else { + $response .= &mt("(You can only create new users in your current role's domain - [_1])",$targetdom); + } + $response .='
      • ' .&mt("Set 'Domain/institution to search' to: [_1]",''.$showdom.'') .'
      • ' .&mt("Set 'Search criteria' to: [_1]username is ..... in selected LON-CAPA domain[_2]",'','') @@ -5346,15 +10195,20 @@ sub build_search_response { .&mt("Click 'Search'") .'

      '; } else { - my $helplink = ' href="javascript:helpMenu('."'display'".')"'; - $response .= '

      ' - .&mt("You are not authorized to create new users in your current role's domain - [_1]." - ,''.$env{'request.role.domain'}.'') - .'
      ' - .&mt('Please contact the [_1]helpdesk[_2] if you need to create a new user.' - ,' ' - ,'') - .'

      '; + unless (($context eq 'domain') && ($env{'form.action'} eq 'singleuser')) { + my $helplink = ' href="javascript:helpMenu('."'display'".')"'; + $response .= '

      '; + if ($context eq 'requestcrs') { + $response .= &mt("You are not authorized to define new users in the new course's domain - [_1].",$targetdom); + } else { + $response .= &mt("You are not authorized to create new users in your current role's domain - [_1].",$targetdom); + } + $response .= '
      ' + .&mt('Please contact the [_1]helpdesk[_2] if you need to create a new user.' + ,' ' + ,'') + .'
      '; + } } } } @@ -5421,7 +10275,8 @@ function backPage(formname,prevphase,pre } sub course_level_table { - my (%inccourses) = @_; + my ($inccourses,$showcredits,$defaultcredits) = @_; + return unless (ref($inccourses) eq 'HASH'); my $table = ''; # Custom Roles? @@ -5436,16 +10291,18 @@ sub course_level_table { 'rol' => "Role", 'ext' => "Extent", 'grs' => "Section", + 'crd' => "Credits", 'sta' => "Start", 'end' => "End" ); - foreach my $protectedcourse (sort( keys(%inccourses))) { + foreach my $protectedcourse (sort(keys(%{$inccourses}))) { my $thiscourse=$protectedcourse; $thiscourse=~s:_:/:g; my %coursedata=&Apache::lonnet::coursedescription($thiscourse); + my $isowner = &Apache::lonuserutils::is_courseowner($protectedcourse,$coursedata{'internal.courseowner'}); my $area=$coursedata{'description'}; - my $type=$coursedata{'type'}; + my $crstype=$coursedata{'type'}; if (!defined($area)) { $area=&mt('Unavailable course').': '.$protectedcourse; } my ($domain,$cnum)=split(/\//,$thiscourse); my %sections_count; @@ -5455,25 +10312,30 @@ sub course_level_table { &Apache::loncommon::get_sections($domain,$cnum); } } - my @roles = &Apache::lonuserutils::roles_by_context('course'); + my @roles = &Apache::lonuserutils::roles_by_context('course','',$crstype); foreach my $role (@roles) { - my $plrole=&Apache::lonnet::plaintext($role); - if (&Apache::lonnet::allowed('c'.$role,$thiscourse)) { + my $plrole=&Apache::lonnet::plaintext($role,$crstype); + if ((&Apache::lonnet::allowed('c'.$role,$thiscourse)) || + ((($role eq 'cc') || ($role eq 'co')) && ($isowner))) { $table .= &course_level_row($protectedcourse,$role,$area,$domain, - $plrole,\%sections_count,\%lt); + $plrole,\%sections_count,\%lt, + $showcredits,$defaultcredits,$crstype); } elsif ($env{'request.course.sec'} ne '') { if (&Apache::lonnet::allowed('c'.$role,$thiscourse.'/'. $env{'request.course.sec'})) { $table .= &course_level_row($protectedcourse,$role,$area,$domain, - $plrole,\%sections_count,\%lt); + $plrole,\%sections_count,\%lt, + $showcredits,$defaultcredits,$crstype); } } } if (&Apache::lonnet::allowed('ccr',$thiscourse)) { - foreach my $cust (sort keys %customroles) { + foreach my $cust (sort(keys(%customroles))) { + next if ($crstype eq 'Community' && $customroles{$cust} =~ /bre\&S/); my $role = 'cr_cr_'.$env{'user.domain'}.'_'.$env{'user.name'}.'_'.$cust; $table .= &course_level_row($protectedcourse,$role,$area,$domain, - $cust,\%sections_count,\%lt); + $cust,\%sections_count,\%lt, + $showcredits,$defaultcredits,$crstype); } } } @@ -5486,8 +10348,14 @@ sub course_level_table { $result .= &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(). -''.$lt{'act'}.''.$lt{'rol'}.''.$lt{'ext'}.' -'.$lt{'grs'}.''.$lt{'sta'}.''.$lt{'end'}.''. +''.$lt{'act'}.''.$lt{'rol'}.''."\n". +''.$lt{'ext'}.''."\n"; + if ($showcredits) { + $result .= $lt{'crd'}.''; + } + $result .= +''.$lt{'grs'}.''.$lt{'sta'}.''."\n". +''.$lt{'end'}.''. &Apache::loncommon::end_data_table_header_row(). $table. &Apache::loncommon::end_data_table(); @@ -5495,13 +10363,22 @@ $table. } sub course_level_row { - my ($protectedcourse,$role,$area,$domain,$plrole,$sections_count,$lt) = @_; + my ($protectedcourse,$role,$area,$domain,$plrole,$sections_count, + $lt,$showcredits,$defaultcredits,$crstype) = @_; + my $creditem; my $row = &Apache::loncommon::start_data_table_row(). ' '."\n". ' '.$plrole.''."\n". ' '.$area.'
      Domain: '.$domain.''."\n"; - if ($role eq 'cc') { + if (($showcredits) && ($role eq 'st') && ($crstype eq 'Course')) { + $row .= + ''; + } else { + $row .= ' '; + } + if (($role eq 'cc') || ($role eq 'co')) { $row .= ' '; } elsif ($env{'request.course.sec'} ne '') { $row .= ' '."\n"; + 'name="sec_'.$protectedcourse.'_'.$role.'" />'."\n"; } } $row .= <'. ''. ''; - my $courseform=''.&Apache::loncommon::selectcourse_link - ('cu','dccourse','dcdomain','coursedesc',undef,undef,'Course').''; - my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($dcdom,'currsec','cu'); + my $courseform=&Apache::loncommon::selectcourse_link + ('cu','dccourse','dcdomain','coursedesc',undef,undef,'Select','crstype'); + my $credit_elem; + if ($showcredits) { + $credit_elem = 'credits'; + } + my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($dcdom,'currsec','cu','role','Course/Community Browser',$credit_elem); my %lt=&Apache::lonlocal::texthash( 'rol' => "Role", 'grs' => "Section", @@ -5559,64 +10440,79 @@ sub course_level_dc { 'sta' => "Start", 'end' => "End", 'ssd' => "Set Start Date", - 'sed' => "Set End Date" + 'sed' => "Set End Date", + 'scc' => "Course/Community", + 'crd' => "Credits", ); - my $header = '

      '.&mt('Course Level').'

      '. + my $header = '

      '.&mt('Course/Community Level').'

      '. &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(). - ''.$courseform.''.$lt{'rol'}.''.$lt{'grs'}.''.$lt{'sta'}.''.$lt{'end'}.''. + ''.$lt{'scc'}.''.$lt{'rol'}.''."\n". + ''.$lt{'grs'}.''."\n"; + $header .= ''.$lt{'crd'}.''."\n" if ($showcredits); + $header .= ''.$lt{'sta'}.''.$lt{'end'}.''."\n". &Apache::loncommon::end_data_table_header_row(); my $otheritems = &Apache::loncommon::start_data_table_row()."\n". - ''."\n". - ''. + $courseform.(' ' x4).''."\n". + '
      '. ''. ''. + ' '. ''. ''. - '
      '.$lt{'exs'}.'
         '.$lt{'new'}.'
      '. ''. ''. - '
      '; + ''. + ''. + ''."\n"; + if ($showcredits) { + $otheritems .= '
      '."\n". + ''."\n"; + } $otheritems .= < +
      $lt{'ssd'} - +
      $lt{'sed'} ENDTIMEENTRY $otheritems .= &Apache::loncommon::end_data_table_row(). &Apache::loncommon::end_data_table()."\n"; - return $cb_jscript.$header.$hiddenitems.$otheritems; + return $cb_jscript.$hiddenitems.$header.$otheritems; } sub update_selfenroll_config { - my ($r,$context,$permission) = @_; - my ($row,$lt) = &get_selfenroll_titles(); - my %curr_groups = &Apache::longroup::coursegroups(); + my ($r,$cid,$cdom,$cnum,$context,$crstype,$currsettings) = @_; + return unless (ref($currsettings) eq 'HASH'); + my ($row,$lt) = &Apache::lonuserutils::get_selfenroll_titles(); + my %curr_groups = &Apache::longroup::coursegroups($cdom,$cnum); my (%changes,%warning); - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $curr_types; + my %noedit; + unless ($context eq 'domain') { + %noedit = &get_noedit_fields($cdom,$cnum,$crstype,$row); + } if (ref($row) eq 'ARRAY') { foreach my $item (@{$row}) { + next if ($noedit{$item}); if ($item eq 'enroll_dates') { my (%currenrolldate,%newenrolldate); foreach my $type ('start','end') { - $currenrolldate{$type} = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$type.'_date'}; + $currenrolldate{$type} = $currsettings->{'selfenroll_'.$type.'_date'}; $newenrolldate{$type} = &Apache::lonhtmlcommon::get_date_from_form('selfenroll_'.$type.'_date'); if ($newenrolldate{$type} ne $currenrolldate{$type}) { $changes{'internal.selfenroll_'.$type.'_date'} = $newenrolldate{$type}; @@ -5625,15 +10521,14 @@ sub update_selfenroll_config { } elsif ($item eq 'access_dates') { my (%currdate,%newdate); foreach my $type ('start','end') { - $currdate{$type} = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$type.'_access'}; + $currdate{$type} = $currsettings->{'selfenroll_'.$type.'_access'}; $newdate{$type} = &Apache::lonhtmlcommon::get_date_from_form('selfenroll_'.$type.'_access'); if ($newdate{$type} ne $currdate{$type}) { $changes{'internal.selfenroll_'.$type.'_access'} = $newdate{$type}; } } } elsif ($item eq 'types') { - $curr_types = - $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$item}; + $curr_types = $currsettings->{'selfenroll_'.$item}; if ($env{'form.selfenroll_all'}) { if ($curr_types ne '*') { $changes{'internal.selfenroll_types'} = '*'; @@ -5658,7 +10553,8 @@ sub update_selfenroll_config { $newnum ++; } } - for (my $j=0; $j<$env{'form.selfenroll_types_total'}; $j++) { if ((!grep(/^$j$/,@deletedoms)) && (!grep(/^$j$/,@activations))) { + for (my $j=0; $j<$env{'form.selfenroll_types_total'}; $j++) { + if ((!grep(/^$j$/,@deletedoms)) && (!grep(/^$j$/,@activations))) { my @types = &Apache::loncommon::get_env_multiple('form.selfenroll_types_'.$j); if (@types > 0) { @types = sort(@types); @@ -5701,9 +10597,9 @@ sub update_selfenroll_config { my $newlimit = $env{'form.selfenroll_limit'}; my $newcap = $env{'form.selfenroll_cap'}; $newcap =~s/\s+//g; - my $currlimit = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_limit'}; + my $currlimit = $currsettings->{'selfenroll_limit'}; $currlimit = 'none' if ($currlimit eq ''); - my $currcap = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_cap'}; + my $currcap = $currsettings->{'selfenroll_cap'}; if ($newlimit ne $currlimit) { if ($newlimit ne 'none') { if ($newcap =~ /^\d+$/) { @@ -5712,7 +10608,8 @@ sub update_selfenroll_config { } $changes{'internal.selfenroll_limit'} = $newlimit; } else { - $warning{$item} = &mt('Maximum enrollment setting unchanged.').'
      '.&mt('The value provided was invalid - it must be a positive integer if enrollment is being limited.'); + $warning{$item} = &mt('Maximum enrollment setting unchanged.').'
      '. + &mt('The value provided was invalid - it must be a positive integer if enrollment is being limited.'); } } elsif ($currcap ne '') { $changes{'internal.selfenroll_cap'} = ''; @@ -5724,13 +10621,14 @@ sub update_selfenroll_config { $changes{'internal.selfenroll_cap'} = $newcap; } } else { - $warning{$item} = &mt('Maximum enrollment setting unchanged.').'
      '.&mt('The value provided was invalid - it must be a positive integer if enrollment is being limited.'); + $warning{$item} = &mt('Maximum enrollment setting unchanged.').'
      '. + &mt('The value provided was invalid - it must be a positive integer if enrollment is being limited.'); } } } elsif ($item eq 'approval') { my (@currnotified,@newnotified); - my $currapproval = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_approval'}; - my $currnotifylist = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_notifylist'}; + my $currapproval = $currsettings->{'selfenroll_approval'}; + my $currnotifylist = $currsettings->{'selfenroll_notifylist'}; if ($currnotifylist ne '') { @currnotified = split(/,/,$currnotifylist); @currnotified = sort(@currnotified); @@ -5766,14 +10664,14 @@ sub update_selfenroll_config { } } } else { - my $curr_val = - $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_'.$item}; + my $curr_val = $currsettings->{'selfenroll_'.$item}; my $newval = $env{'form.selfenroll_'.$item}; if ($item eq 'section') { $newval = $env{'form.sections'}; if (defined($curr_groups{$newval})) { $newval = $curr_val; - $warning{$item} = &mt('Section for self-enrolled users unchanged as the proposed section is a group').'
      '.&mt('Group names and section names must be distinct'); + $warning{$item} = &mt('Section for self-enrolled users unchanged as the proposed section is a group').'
      '. + &mt('Group names and section names must be distinct'); } elsif ($newval eq 'all') { $newval = $curr_val; $warning{$item} = &mt('Section for self-enrolled users unchanged, as "all" is a reserved section name.'); @@ -5803,11 +10701,10 @@ sub update_selfenroll_config { my %crsinfo = &Apache::lonnet::courseiddump($cdom,'.',1,'.','.', $cnum,undef,undef,'Course'); my $chome = &Apache::lonnet::homeserver($cnum,$cdom); - if (ref($crsinfo{$env{'request.course.id'}}) eq 'HASH') { + if (ref($crsinfo{$cid}) eq 'HASH') { foreach my $item ('selfenroll_types','selfenroll_start_date','selfenroll_end_date') { if (exists($changes{'internal.'.$item})) { - $crsinfo{$env{'request.course.id'}}{$item} = - $changes{'internal.'.$item}; + $crsinfo{$cid}{$item} = $changes{'internal.'.$item}; } } my $crsputresult = @@ -5844,7 +10741,7 @@ sub update_selfenroll_config { if ($changes{'internal.selfenroll_cap'} ne '') { $newcap = $changes{'internal.selfenroll_cap'} } else { - $newcap = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_cap'}; + $newcap = $currsettings->{'selfenroll_cap'}; } if ($changes{'internal.selfenroll_limit'} eq 'none') { $newval = &mt('No limit'); @@ -5854,11 +10751,11 @@ sub update_selfenroll_config { } elsif ($changes{'internal.selfenroll_limit'} eq 'selfenrolled') { $newval = &mt('New self-enrollment no longer allowed when total number of self-enrolled students reaches [_1].',$newcap); } else { - my $currlimit = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_limit'}; + my $currlimit = $currsettings->{'selfenroll_limit'}; if ($currlimit eq 'allstudents') { $newval = &mt('New self-enrollment no longer allowed when total (all students) reaches [_1].',$newcap); } elsif ($changes{'internal.selfenroll_limit'} eq 'selfenrolled') { - $newval = &mt('New self-enrollment no longer allowed when total umber of self-enrolled students reaches [_1].',$newcap); + $newval = &mt('New self-enrollment no longer allowed when total number of self-enrolled students reaches [_1].',$newcap); } } $r->print('
    • '.&mt('"[_1]" set to "[_2]".',$title,$newval).'
    • '."\n"); @@ -5866,24 +10763,24 @@ sub update_selfenroll_config { } elsif ($item eq 'approval') { if ((exists($changes{'internal.selfenroll_approval'})) || (exists($changes{'internal.selfenroll_notifylist'}))) { + my %selfdescs = &Apache::lonuserutils::selfenroll_default_descs(); my ($newval,$newnotify); if (exists($changes{'internal.selfenroll_notifylist'})) { $newnotify = $changes{'internal.selfenroll_notifylist'}; } else { - $newnotify = $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_notifylist'}; + $newnotify = $currsettings->{'selfenroll_notifylist'}; } - if ($changes{'internal.selfenroll_approval'}) { - $newval = &mt('Yes'); - } elsif ($changes{'internal.selfenroll_approval'} eq '0') { - $newval = &mt('No'); + if (exists($changes{'internal.selfenroll_approval'})) { + if ($changes{'internal.selfenroll_approval'} !~ /^[012]$/) { + $changes{'internal.selfenroll_approval'} = '0'; + } + $newval = $selfdescs{'approval'}{$changes{'internal.selfenroll_approval'}}; } else { - my $currapproval = - $env{'course.'.$env{'request.course.id'}.'.internal.selfenroll_approval'}; - if ($currapproval) { - $newval = &mt('Yes'); - } else { - $newval = &mt('No'); + my $currapproval = $currsettings->{'selfenroll_approval'}; + if ($currapproval !~ /^[012]$/) { + $currapproval = 0; } + $newval = $selfdescs{'approval'}{$currapproval}; } $r->print('
    • '.&mt('"[_1]" set to "[_2]".',$title,$newval)); if ($newnotify) { @@ -5914,13 +10811,16 @@ sub update_selfenroll_config { } } $r->print('
    '); - my %newenvhash; - foreach my $key (keys(%changes)) { - $newenvhash{'course.'.$env{'request.course.id'}.'.'.$key} = $changes{$key}; + if ($env{'course.'.$cid.'.description'} ne '') { + my %newenvhash; + foreach my $key (keys(%changes)) { + $newenvhash{'course.'.$cid.'.'.$key} = $changes{$key}; + } + &Apache::lonnet::appenv(\%newenvhash); } - &Apache::lonnet::appenv(\%newenvhash); } else { - $r->print(&mt('An error occurred when saving changes to self-enrollment settings in this course.').'
    '.&mt('The error was: [_1].',$putresult)); + $r->print(&mt('An error occurred when saving changes to self-enrollment settings in this course.').'
    '. + &mt('The error was: [_1].',$putresult)); } } else { $r->print(&mt('No changes were made to the existing self-enrollment settings in this course.')); @@ -5928,39 +10828,54 @@ sub update_selfenroll_config { } else { $r->print(&mt('No changes were made to the existing self-enrollment settings in this course.')); } - my ($visible,$cansetvis,$vismsgs,$visactions) = &visible_in_cat($cdom,$cnum); - if (ref($visactions) eq 'HASH') { - if (!$visible) { - $r->print('
    '.$visactions->{'miss'}.'
    '.$visactions->{'yous'}. - '
    '); - if (ref($vismsgs) eq 'ARRAY') { - $r->print('
    '.$visactions->{'take'}.'
      '); - foreach my $item (@{$vismsgs}) { - $r->print('
    • '.$visactions->{$item}.'
    • '); + my $visactions = &cat_visibility($cdom); + my ($cathash,%cattype); + my %domconfig = &Apache::lonnet::get_dom('configuration',['coursecategories'],$cdom); + if (ref($domconfig{'coursecategories'}) eq 'HASH') { + $cathash = $domconfig{'coursecategories'}{'cats'}; + $cattype{'auth'} = $domconfig{'coursecategories'}{'auth'}; + $cattype{'unauth'} = $domconfig{'coursecategories'}{'unauth'}; + } else { + $cathash = {}; + $cattype{'auth'} = 'std'; + $cattype{'unauth'} = 'std'; + } + if (($cattype{'auth'} eq 'none') && ($cattype{'unauth'} eq 'none')) { + $r->print('
      '.$visactions->{'miss'}.'
      '.$visactions->{'yous'}. + '
      '. + '
      '.$visactions->{'take'}.'
        '. + '
      • '.$visactions->{'dc_chgconf'}.'
      • '. + '
      '); + } elsif (($cattype{'auth'} !~ /^(std|domonly)$/) && ($cattype{'unauth'} !~ /^(std|domonly)$/)) { + if ($currsettings->{'uniquecode'}) { + $r->print(''.$visactions->{'vis'}.''); + } else { + $r->print('
      '.$visactions->{'miss'}.'
      '.$visactions->{'yous'}. + '
      '. + '
      '.$visactions->{'take'}.'
        '. + '
      • '.$visactions->{'dc_setcode'}.'
      • '. + '

      '); + } + } else { + my ($visible,$cansetvis,$vismsgs) = &visible_in_stdcat($cdom,$cnum,\%domconfig); + if (ref($visactions) eq 'HASH') { + if (!$visible) { + $r->print('
      '.$visactions->{'miss'}.'
      '.$visactions->{'yous'}. + '
      '); + if (ref($vismsgs) eq 'ARRAY') { + $r->print('
      '.$visactions->{'take'}.'
        '); + foreach my $item (@{$vismsgs}) { + $r->print('
      • '.$visactions->{$item}.'
      • '); + } + $r->print('
      '); } - $r->print('
    '); + $r->print($cansetvis); } - $r->print($cansetvis); } } return; } -sub get_selfenroll_titles { - my @row = ('types','registered','enroll_dates','access_dates','section', - 'approval','limit'); - my %lt = &Apache::lonlocal::texthash ( - types => 'Users allowed to self-enroll in this course', - registered => 'Restrict self-enrollment to students officially registered for the course', - enroll_dates => 'Dates self-enrollment available', - access_dates => 'Course access dates assigned to self-enrolling users', - section => 'Section assigned to self-enrolling users', - approval => 'Self-enrollment requests need approval?', - limit => 'Enrollment limit', - ); - return (\@row,\%lt); -} - #---------------------------------------------- end functions for &phase_two #--------------------------------- functions for &phase_two and &phase_three