# The LearningOnline Network with CAPA # Utility functions for managing LON-CAPA user accounts # # $Id: lonuserutils.pm,v 1.81 2009/02/18 19:34:08 schafran Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA# # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # # ############################################################### ############################################################### package Apache::lonuserutils; use strict; use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon; use Apache::lonlocal; use Apache::longroup; use LONCAPA qw(:DEFAULT :match); ############################################################### ############################################################### # Drop student from all sections of a course, except optional $csec sub modifystudent { my ($udom,$unam,$courseid,$csec,$desiredhost,$context)=@_; # if $csec is undefined, drop the student from all the courses matching # this one. If $csec is defined, drop them from all other sections of # this course and add them to section $csec my ($cnum,$cdom) = &get_course_identity($courseid); my %roles = &Apache::lonnet::dump('roles',$udom,$unam); my ($tmp) = keys(%roles); # Bail out if we were unable to get the students roles return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i); # Go through the roles looking for enrollment in this course my $result = ''; foreach my $course (keys(%roles)) { if ($course=~m{^/\Q$cdom\E/\Q$cnum\E(?:\/)*(?:\s+)*(\w+)*\_st$}) { # We are in this course my $section=$1; $section='' if ($course eq "/$cdom/$cnum".'_st'); if (defined($csec) && $section eq $csec) { $result .= 'ok:'; } elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) { my (undef,$end,$start)=split(/\_/,$roles{$course}); my $now=time; # if this is an active role if (!($start && ($now<$start)) || !($end && ($now>$end))) { my $reply=&Apache::lonnet::modifystudent # dom name id mode pass f m l g ($udom,$unam,'', '', '',undef,undef,undef,undef, $section,time,undef,undef,$desiredhost,'','manual', '',$courseid,'',$context); $result .= $reply.':'; } } } } if ($result eq '') { $result = &mt('Unable to find section for this student'); } else { $result =~ s/(ok:)+/ok/g; } return $result; } sub modifyuserrole { my ($context,$setting,$changeauth,$cid,$udom,$uname,$uid,$umode,$upass, $first,$middle,$last,$gene,$sec,$forceid,$desiredhome,$email,$role, $end,$start,$checkid) = @_; my ($scope,$userresult,$authresult,$roleresult,$idresult); if ($setting eq 'course' || $context eq 'course') { $scope = '/'.$cid; $scope =~ s/\_/\//g; if ($role ne 'cc' && $sec ne '') { $scope .='/'.$sec; } } elsif ($context eq 'domain') { $scope = '/'.$env{'request.role.domain'}.'/'; } elsif ($context eq 'author') { $scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'}; } if ($context eq 'domain') { my $uhome = &Apache::lonnet::homeserver($uname,$udom); if ($uhome ne 'no_host') { if (($changeauth eq 'Yes') && (&Apache::lonnet::allowed('mau',$udom))) { if ((($umode =~ /^krb4|krb5|internal$/) && $upass ne '') || ($umode eq 'localauth')) { $authresult = &Apache::lonnet::modifyuserauth($udom,$uname,$umode,$upass); } } if (($forceid) && (&Apache::lonnet::allowed('mau',$udom)) && ($env{'form.recurseid'}) && ($checkid)) { my %userupdate = ( lastname => $last, middlename => $middle, firstname => $first, generation => $gene, id => $uid, ); $idresult = &propagate_id_change($uname,$udom,\%userupdate); } } } $userresult = &Apache::lonnet::modifyuser($udom,$uname,$uid,$umode,$upass,$first, $middle,$last,$gene,$forceid,$desiredhome, $email,$role,$start,$end); if ($userresult eq 'ok') { if ($role ne '') { $role =~ s/_/\//g; $roleresult = &Apache::lonnet::assignrole($udom,$uname,$scope, $role,$end,$start,'', '',$context); } } return ($userresult,$authresult,$roleresult,$idresult); } sub propagate_id_change { my ($uname,$udom,$user) = @_; my (@types,@roles); @types = ('active','future'); @roles = ('st'); my $idresult; my %roleshash = &Apache::lonnet::get_my_roles($uname, $udom,'userroles',\@types,\@roles); my %args = ( one_time => 1, ); foreach my $item (keys(%roleshash)) { my ($cnum,$cdom,$role) = split(/:/,$item,-1); my ($start,$end) = split(/:/,$roleshash{$item}); if (&Apache::lonnet::is_course($cdom,$cnum)) { my $result = &update_classlist($cdom,$cnum,$udom,$uname,$user); my %coursehash = &Apache::lonnet::coursedescription($cdom.'_'.$cnum,\%args); my $cdesc = $coursehash{'description'}; if ($cdesc eq '') { $cdesc = $cdom.'_'.$cnum; } if ($result eq 'ok') { $idresult .= &mt('Classlist update for "[_1]" in "[_2]".',$uname.':'.$udom,$cdesc).'
'."\n"; } else { $idresult .= &mt('Error: "[_1]" during classlist update for "[_2]" in "[_3]".',$result,$uname.':'.$udom,$cdesc).'
'."\n"; } } } return $idresult; } sub update_classlist { my ($cdom,$cnum,$udom,$uname,$user,$newend) = @_; my ($uid,$classlistentry); my $fullname = &Apache::lonnet::format_name($user->{'firstname'},$user->{'middlename'}, $user->{'lastname'},$user->{'generation'}, 'lastname'); my %classhash = &Apache::lonnet::get('classlist',[$uname.':'.$udom], $cdom,$cnum); my @classinfo = split(/:/,$classhash{$uname.':'.$udom}); my $ididx=&Apache::loncoursedata::CL_ID() - 2; my $nameidx=&Apache::loncoursedata::CL_FULLNAME() - 2; my $endidx = &Apache::loncoursedata::CL_END() - 2; my $startidx = &Apache::loncoursedata::CL_START() - 2; for (my $i=0; $i<@classinfo; $i++) { if ($i == $endidx) { if ($newend ne '') { $classlistentry .= $newend.':'; } else { $classlistentry .= $classinfo[$i].':'; } } elsif ($i == $startidx) { if ($newend ne '') { if ($classinfo[$i] > $newend) { $classlistentry .= $newend.':'; } else { $classlistentry .= $classinfo[$i].':'; } } else { $classlistentry .= $classinfo[$i].':'; } } elsif ($i == $ididx) { if (defined($user->{'id'})) { $classlistentry .= $user->{'id'}.':'; } else { $classlistentry .= $classinfo[$i].':'; } } elsif ($i == $nameidx) { if (defined($user->{'lastname'})) { $classlistentry .= $fullname.':'; } else { $classlistentry .= $classinfo[$i].':'; } } else { $classlistentry .= $classinfo[$i].':'; } } $classlistentry =~ s/:$//; my $reply=&Apache::lonnet::cput('classlist', {"$uname:$udom" => $classlistentry}, $cdom,$cnum); if (($reply eq 'ok') || ($reply eq 'delayed')) { return 'ok'; } else { return 'error: '.$reply; } } ############################################################### ############################################################### # build a role type and role selection form sub domain_roles_select { # Set up the role type and role selection boxes when in # domain context # # Role types my @roletypes = ('domain','author','course'); my %lt = &role_type_names(); # # build up the menu information to be passed to # &Apache::loncommon::linked_select_forms my %select_menus; if ($env{'form.roletype'} eq '') { $env{'form.roletype'} = 'domain'; } foreach my $roletype (@roletypes) { # set up the text for this domain $select_menus{$roletype}->{'text'}= $lt{$roletype}; # we want a choice of 'default' as the default in the second menu if ($env{'form.roletype'} ne '') { $select_menus{$roletype}->{'default'} = $env{'form.showrole'}; } else { $select_menus{$roletype}->{'default'} = 'Any'; } # Now build up the other items in the second menu my @roles; if ($roletype eq 'domain') { @roles = &domain_roles(); } elsif ($roletype eq 'author') { @roles = &construction_space_roles(); } else { my $custom = 1; @roles = &course_roles('domain',undef,$custom); } my $order = ['Any',@roles]; $select_menus{$roletype}->{'order'} = $order; foreach my $role (@roles) { if ($role eq 'cr') { $select_menus{$roletype}->{'select2'}->{$role} = &mt('Custom role'); } else { $select_menus{$roletype}->{'select2'}->{$role} = &Apache::lonnet::plaintext($role); } } $select_menus{$roletype}->{'select2'}->{'Any'} = &mt('Any'); } my $result = &Apache::loncommon::linked_select_forms ('studentform',(' 'x3).&mt('Role: '),$env{'form.roletype'}, 'roletype','showrole',\%select_menus,['domain','author','course']); return $result; } ############################################################### ############################################################### sub hidden_input { my ($name,$value) = @_; return ''."\n"; } sub print_upload_manager_header { my ($r,$datatoken,$distotal,$krbdefdom,$context,$permission)=@_; my $javascript; # if (! exists($env{'form.upfile_associate'})) { $env{'form.upfile_associate'} = 'forward'; } if ($env{'form.associate'} eq 'Reverse Association') { if ( $env{'form.upfile_associate'} ne 'reverse' ) { $env{'form.upfile_associate'} = 'reverse'; } else { $env{'form.upfile_associate'} = 'forward'; } } if ($env{'form.upfile_associate'} eq 'reverse') { $javascript=&upload_manager_javascript_reverse_associate(); } else { $javascript=&upload_manager_javascript_forward_associate(); } # # Deal with restored settings my $password_choice = ''; if (exists($env{'form.ipwd_choice'}) && $env{'form.ipwd_choice'} ne '') { # If a column was specified for password, assume it is for an # internal password. This is a bug waiting to be filed (could be # local or krb auth instead of internal) but I do not have the # time to mess around with this now. $password_choice = 'int'; } # my $groupslist; if ($context eq 'course') { $groupslist = &get_groupslist(); } my $javascript_validations = &javascript_validations('upload',$krbdefdom,$password_choice,undef, $env{'request.role.domain'},$context, $groupslist); my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':''); $r->print(&mt('Total number of records found in file: [_1]',''.$distotal.''). "
\n"); $r->print('

'. &mt('Identify fields in uploaded list')."

\n"); $r->print(&mt('Enter as many fields as you can.
The system will inform you and bring you back to this page,
if the data selected are insufficient to add users.')."
\n"); $r->print(&hidden_input('action','upload'). &hidden_input('state','got_file'). &hidden_input('associate',''). &hidden_input('datatoken',$datatoken). &hidden_input('fileupload',$env{'form.fileupload'}). &hidden_input('upfiletype',$env{'form.upfiletype'}). &hidden_input('upfile_associate',$env{'form.upfile_associate'})); $r->print('

'); $r->print('
'); $r->print("

\n". ''); } ############################################################### ############################################################### sub javascript_validations { my ($mode,$krbdefdom,$curr_authtype,$curr_authfield,$domain, $context,$groupslist)=@_; my %param = ( kerb_def_dom => $krbdefdom, curr_authtype => $curr_authtype, ); if ($mode eq 'upload') { $param{'formname'} = 'studentform'; } elsif ($mode eq 'createcourse') { $param{'formname'} = 'ccrs'; } elsif ($mode eq 'modifycourse') { $param{'formname'} = 'cmod'; $param{'mode'} = 'modifycourse', $param{'curr_autharg'} = $curr_authfield; } my ($setsection_call,$setsections_js); my $finish = " vf.submit();\n"; if ($mode eq 'upload') { if (($context eq 'course') || ($context eq 'domain')) { if ($context eq 'course') { if ($env{'request.course.sec'} eq '') { $setsection_call = 'setSections(document.'.$param{'formname'}.');'; $setsections_js = &setsections_javascript($param{'formname'},$groupslist, $mode); } else { $setsection_call = "'ok'"; } } elsif ($context eq 'domain') { $setsection_call = 'setCourse()'; $setsections_js = &dc_setcourse_js($param{'formname'},$mode,$context); } $finish = " var checkSec = $setsection_call\n". " if (checkSec == 'ok') {\n". " vf.submit();\n". " }\n"; } } my $authheader = &Apache::loncommon::authform_header(%param); my %alert = &Apache::lonlocal::texthash (username => 'You need to specify the username field.', authen => 'You must choose an authentication type.', krb => 'You need to specify the Kerberos domain.', ipass => 'You need to specify the initial password.', name => 'The optional name field was not specified.', snum => 'The optional ID number field was not specified.', section => 'The optional section field was not specified.', email => 'The optional e-mail address field was not specified.', role => 'The optional role field was not specified.', domain => 'The optional domain field was not specified.', continue => 'Continue adding users?', ); my $function_name = <<"END"; $setsections_js function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain) { END my ($authnum,%can_assign) = &Apache::loncommon::get_assignable_auth($domain); my $auth_checks; if ($mode eq 'createcourse') { $auth_checks .= (< 1) { $auth_checks .= (<=2) && (tw<=6)) { foundname=1; } if (tw==7) { foundid=1; } if (tw==8) { foundsec=1; } if (tw==9) { foundpwd=1; } if (tw==10) { foundemail=1; } if (tw==11) { foundrole=1; } if (tw==12) { founddomain=1; } } verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail,foundrole,founddomain); } // // vf = this.form // tf = column number // // values of nw // // 0 = none // 1 = username // 2 = names (lastname, firstnames) // 3 = fname (firstname) // 4 = mname (middlename) // 5 = lname (lastname) // 6 = gen (generation) // 7 = id // 8 = section // 9 = ipwd (password) // 10 = email address // 11 = role // 12 = domain function flip(vf,tf) { var nw=eval('vf.f'+tf+'.selectedIndex'); var i; // make sure no other columns are labeled the same as this one for (i=0;i<=vf.nfields.value;i++) { if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) { eval('vf.f'+i+'.selectedIndex=0;') } } // If we set this to 'lastname, firstnames', clear out all the ones // set to 'fname','mname','lname','gen' (3,4,5,6) currently. if (nw==2) { for (i=0;i<=vf.nfields.value;i++) { if ((eval('vf.f'+i+'.selectedIndex')>=3) && (eval('vf.f'+i+'.selectedIndex')<=6)) { eval('vf.f'+i+'.selectedIndex=0;') } } } // If we set this to one of 'fname','mname','lname','gen' (3,4,5,6), // clear out any that are set to 'lastname, firstnames' (2) if ((nw>=3) && (nw<=6)) { for (i=0;i<=vf.nfields.value;i++) { if (eval('vf.f'+i+'.selectedIndex')==2) { eval('vf.f'+i+'.selectedIndex=0;') } } } // If we set the password, make the password form below correspond to // the new value. if (nw==9) { changed_radio('int',document.studentform); set_auth_radio_buttons('int',document.studentform); vf.intarg.value=''; vf.krbarg.value=''; vf.locarg.value=''; } } function clearpwd(vf) { var i; for (i=0;i<=vf.nfields.value;i++) { if (eval('vf.f'+i+'.selectedIndex')==9) { eval('vf.f'+i+'.selectedIndex=0;') } } } ENDPICK } ############################################################### ############################################################### sub upload_manager_javascript_reverse_associate { return(<=1) && (i<=5)) && tw!=0 ) { foundname=1; } if (i==6 && tw!=0) { foundid=1; } if (i==7 && tw!=0) { foundsec=1; } if (i==8 && tw!=0) { foundpwd=1; } if (i==9 && tw!=0) { foundrole=1; } if (i==10 && tw!=0) { founddomain=1; } } verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundrole,founddomain); } function flip(vf,tf) { var nw=eval('vf.f'+tf+'.selectedIndex'); var i; // picked the all one name field, reset the other name ones to blank if (tf==1 && nw!=0) { for (i=2;i<=5;i++) { eval('vf.f'+i+'.selectedIndex=0;') } } //picked one of the piecewise name fields, reset the all in //one field to blank if ((tf>=2) && (tf<=5) && (nw!=0)) { eval('vf.f1.selectedIndex=0;') } // intial password specified, pick internal authentication if (tf==8 && nw!=0) { changed_radio('int',document.studentform); set_auth_radio_buttons('int',document.studentform); vf.krbarg.value=''; vf.intarg.value=''; vf.locarg.value=''; } } function clearpwd(vf) { var i; if (eval('vf.f8.selectedIndex')!=0) { eval('vf.f8.selectedIndex=0;') } } ENDPICK } ############################################################### ############################################################### sub print_upload_manager_footer { my ($r,$i,$keyfields,$defdom,$today,$halfyear,$context,$permission) = @_; my $form = 'document.studentform'; my $formname = 'studentform'; my ($krbdef,$krbdefdom) = &Apache::loncommon::get_kerberos_defaults($defdom); my %param = ( formname => $form, kerb_def_dom => $krbdefdom, kerb_def_auth => $krbdef ); if (exists($env{'form.ipwd_choice'}) && defined($env{'form.ipwd_choice'}) && $env{'form.ipwd_choice'} ne '') { $param{'curr_authtype'} = 'int'; } my $krbform = &Apache::loncommon::authform_kerberos(%param); my $intform = &Apache::loncommon::authform_internal(%param); my $locform = &Apache::loncommon::authform_local(%param); my $date_table = &date_setting_table(undef,undef,$context,undef, $formname,$permission); my $Str = "\n".'
'; $Str .= &hidden_input('nfields',$i); $Str .= &hidden_input('keyfields',$keyfields); $Str .= "

".&mt('Login Type')."

\n"; if ($context eq 'domain') { $Str .= '

'.&mt('Change authentication for existing users in domain "[_1]" to these settings?',$defdom).'   

'; } else { $Str .= "

\n". &mt('Note: This will not take effect if the user already exists.'). &Apache::loncommon::help_open_topic('Auth_Options'). "

\n"; } $Str .= &set_login($defdom,$krbform,$intform,$locform); my ($home_server_pick,$numlib) = &Apache::loncommon::home_server_form_item($defdom,'lcserver', 'default','hide'); if ($numlib > 1) { $Str .= '

'.&mt('LON-CAPA Home Server for New Users')."

\n". &mt('LON-CAPA domain: [_1] with home server: [_2]',$defdom, $home_server_pick).'
'; } else { $Str .= $home_server_pick; } $Str .= '

'.&mt('Default domain').'

'."\n". &Apache::loncommon::select_dom_form($defdom,'defaultdomain',undef,1); $Str .= '

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

\n"; $Str .= "

\n".$date_table."

\n"; if ($context eq 'domain') { $Str .= '

'.&mt('Settings for assigning roles:').'

'."\n". &mt('Pick the action to take on roles for these users:').'
      '; } if ($context eq 'author') { $Str .= '

'.&mt('Default role')."

\n". &mt('Choose the role to assign to users without a value specified in the uploaded file'); } elsif ($context eq 'course') { $Str .= '

'.&mt('Default role and section')."

\n". &mt('Choose the role and/or section(s) to assign to users without values specified in the uploaded file'); } else { $Str .= '

'.&mt('Default role and/or section(s)')."
\n". &mt('Role and/or section(s) for users without values specified in the uploaded file.'); } $Str .= '
'; if (($context eq 'domain') || ($context eq 'author')) { my ($options,$cb_script,$coursepick) = &default_role_selector($context,1); if ($context eq 'domain') { $Str .= ''.&mt('Domain Level').'
'.$options.'

'.&mt('Course Level').'
'.$cb_script.$coursepick; } elsif ($context eq 'author') { $Str .= $options; } } else { my ($cnum,$cdom) = &get_course_identity(); my $rowtitle = &mt('section'); my $secbox = §ion_picker($cdom,$cnum,'Any',$rowtitle, $permission,$context,'upload'); $Str .= $secbox."

".&mt('Full Update')."

\n". '


'.&mt('Students selected from this list can be dropped.').'

'."\n"; } if ($context eq 'course' || $context eq 'domain') { $Str .= &forceid_change($context); } $Str .= '
'; $Str .= ''; $r->print($Str); return; } sub forceid_change { my ($context) = @_; my $output = "

".&mt('Student/Employee ID')."

\n". "

\n".'
'."\n". &mt('(only do if you know what you are doing.)')."\n"; if ($context eq 'domain') { $output .= '
'."\n"; } $output .= '

'; return $output; } ############################################################### ############################################################### sub print_upload_manager_form { my ($r,$context,$permission) = @_; my $firstLine; my $datatoken; if (!$env{'form.datatoken'}) { $datatoken=&Apache::loncommon::upfile_store($r); } else { $datatoken=$env{'form.datatoken'}; &Apache::loncommon::load_tmp_file($r); } my @records=&Apache::loncommon::upfile_record_sep(); if($env{'form.noFirstLine'}){ $firstLine=shift(@records); } my $total=$#records; my $distotal=$total+1; my $today=time; my $halfyear=$today+15552000; # # Restore memorized settings my $col_setting_names = { 'username_choice' => 'scalar', # column settings 'names_choice' => 'scalar', 'fname_choice' => 'scalar', 'mname_choice' => 'scalar', 'lname_choice' => 'scalar', 'gen_choice' => 'scalar', 'id_choice' => 'scalar', 'sec_choice' => 'scalar', 'ipwd_choice' => 'scalar', 'email_choice' => 'scalar', 'role_choice' => 'scalar', 'domain_choice' => 'scalar', }; my $defdom = $env{'request.role.domain'}; if ($context eq 'course') { &Apache::loncommon::restore_course_settings('enrollment_upload', $col_setting_names); } else { &Apache::loncommon::restore_settings($context,'user_upload', $col_setting_names); } # # Determine kerberos parameters as appropriate my ($krbdef,$krbdefdom) = &Apache::loncommon::get_kerberos_defaults($defdom); # &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom,$context, $permission); my $i; my $keyfields; if ($total>=0) { my @field= (['username',&mt('Username'), $env{'form.username_choice'}], ['names',&mt('Last Name, First Names'),$env{'form.names_choice'}], ['fname',&mt('First Name'), $env{'form.fname_choice'}], ['mname',&mt('Middle Names/Initials'),$env{'form.mname_choice'}], ['lname',&mt('Last Name'), $env{'form.lname_choice'}], ['gen', &mt('Generation'), $env{'form.gen_choice'}], ['id', &mt('Student/Employee ID'),$env{'form.id_choice'}], ['sec', &mt('Section'), $env{'form.sec_choice'}], ['ipwd', &mt('Initial Password'),$env{'form.ipwd_choice'}], ['email',&mt('E-mail Address'), $env{'form.email_choice'}], ['role',&mt('Role'), $env{'form.role_choice'}], ['domain',&mt('Domain'), $env{'form.domain_choice'}]); if ($env{'form.upfile_associate'} eq 'reverse') { &Apache::loncommon::csv_print_samples($r,\@records); $i=&Apache::loncommon::csv_print_select_table($r,\@records, \@field); foreach (@field) { $keyfields.=$_->[0].','; } chop($keyfields); } else { unshift(@field,['none','']); $i=&Apache::loncommon::csv_samples_select_table($r,\@records, \@field); my %sone=&Apache::loncommon::record_sep($records[0]); $keyfields=join(',',sort(keys(%sone))); } } $r->print('
'); &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear, $context,$permission); } sub setup_date_selectors { my ($starttime,$endtime,$mode,$nolink,$formname) = @_; if ($formname eq '') { $formname = 'studentform'; } if (! defined($starttime)) { $starttime = time; unless ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') { if (exists($env{'course.'.$env{'request.course.id'}. '.default_enrollment_start_date'})) { $starttime = $env{'course.'.$env{'request.course.id'}. '.default_enrollment_start_date'}; } } } if (! defined($endtime)) { $endtime = time+(6*30*24*60*60); # 6 months from now, approx unless ($mode eq 'createcourse') { if (exists($env{'course.'.$env{'request.course.id'}. '.default_enrollment_end_date'})) { $endtime = $env{'course.'.$env{'request.course.id'}. '.default_enrollment_end_date'}; } } } my $startdateform = &Apache::lonhtmlcommon::date_setter($formname,'startdate',$starttime, undef,undef,undef,undef,undef,undef,undef,$nolink); my $enddateform = &Apache::lonhtmlcommon::date_setter($formname,'enddate',$endtime, undef,undef,undef,undef,undef,undef,undef,$nolink); if ($mode eq 'create_enrolldates') { $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs', 'startenroll', $starttime); $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs', 'endenroll', $endtime); } if ($mode eq 'create_defaultdates') { $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs', 'startaccess', $starttime); $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs', 'endaccess', $endtime); } return ($startdateform,$enddateform); } sub get_dates_from_form { my ($startname,$endname) = @_; if ($startname eq '') { $startname = 'startdate'; } if ($endname eq '') { $endname = 'enddate'; } my $startdate = &Apache::lonhtmlcommon::get_date_from_form($startname); my $enddate = &Apache::lonhtmlcommon::get_date_from_form($endname); if ($env{'form.no_end_date'}) { $enddate = 0; } return ($startdate,$enddate); } sub date_setting_table { my ($starttime,$endtime,$mode,$bulkaction,$formname,$permission) = @_; my $nolink; if ($bulkaction) { $nolink = 1; } my ($startform,$endform) = &setup_date_selectors($starttime,$endtime,$mode,$nolink,$formname); my $dateDefault; if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') { $dateDefault = ' '; } elsif ($mode ne 'author' && $mode ne 'domain') { if (($bulkaction eq 'reenable') || ($bulkaction eq 'activate') || ($bulkaction eq 'chgdates') || ($env{'form.action'} eq 'upload')) { if ($env{'request.course.sec'} eq '') { $dateDefault = ''. ''; } } } my $perpetual = ''; if ($mode eq 'create_enrolldates') { $perpetual = ' '; } my $result = &Apache::lonhtmlcommon::start_pick_box()."\n"; $result .= &Apache::lonhtmlcommon::row_title(&mt('Starting Date'), 'LC_oddrow_value')."\n". $startform."\n". &Apache::lonhtmlcommon::row_closure(1). &Apache::lonhtmlcommon::row_title(&mt('Ending Date'), 'LC_oddrow_value')."\n". $endform.' '.$perpetual. &Apache::lonhtmlcommon::row_closure(1). &Apache::lonhtmlcommon::end_pick_box(); if ($dateDefault) { $result .= $dateDefault.'
'."\n"; } return $result; } sub make_dates_default { my ($startdate,$enddate,$context) = @_; my $result = ''; if ($context eq 'course') { my ($cnum,$cdom) = &get_course_identity(); my $put_result = &Apache::lonnet::put('environment', {'default_enrollment_start_date'=>$startdate, 'default_enrollment_end_date' =>$enddate},$cdom,$cnum); if ($put_result eq 'ok') { $result .= &mt('Set default start and end access dates for course.'). '
'."\n"; # # Refresh the course environment &Apache::lonnet::coursedescription($env{'request.course.id'}, {'freshen_cache' => 1}); } else { $result .= &mt('Unable to set default access dates for course.').":".$put_result. '
'; } } return $result; } sub default_role_selector { my ($context,$checkpriv) = @_; my %customroles; my ($options,$coursepick,$cb_jscript); if ($context ne 'author') { %customroles = &my_custom_roles(); } my %lt=&Apache::lonlocal::texthash( 'rol' => "Role", 'grs' => "Section", 'exs' => "Existing sections", 'new' => "New section", ); $options = ''."\n". ''. ''. ''. ''. '
'. $lt{'exs'}.'
  '.$lt{'new'}.'
'. ''. ''. ''. ''. ''. ''. '
'. &Apache::loncommon::end_data_table_row(). &Apache::loncommon::end_data_table()."\n"; } $options .= ''; return ($options,$cb_jscript,$coursepick); } sub default_course_roles { my ($context,$checkpriv,%customroles) = @_; my $output; my $custom = 1; my @roles = &course_roles($context,$checkpriv,$custom); foreach my $role (@roles) { if ($role ne 'cr') { my $plrole=&Apache::lonnet::plaintext($role); $output .= ' '; } } if (keys(%customroles) > 0) { if (grep(/^cr$/,@roles)) { foreach my $cust (sort(keys(%customroles))) { my $custrole='cr_'.$env{'user.domain'}. '_'.$env{'user.name'}.'_'.$cust; $output .= ' '; } } } return $output; } sub construction_space_roles { my ($checkpriv) = @_; my @allroles = &roles_by_context('author'); my @roles; if ($checkpriv) { foreach my $role (@allroles) { if (&Apache::lonnet::allowed('c'.$role,$env{'user.domain'}.'/'.$env{'user.name'})) { push(@roles,$role); } } return @roles; } else { return @allroles; } } sub domain_roles { my ($checkpriv) = @_; my @allroles = &roles_by_context('domain'); my @roles; if ($checkpriv) { foreach my $role (@allroles) { if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) { push(@roles,$role); } } return @roles; } else { return @allroles; } } sub course_roles { my ($context,$checkpriv,$custom) = @_; my @allroles = &roles_by_context('course',$custom); my @roles; if ($context eq 'domain') { @roles = @allroles; } elsif ($context eq 'course') { if ($env{'request.course.id'}) { if ($checkpriv) { foreach my $role (@allroles) { if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) { push(@roles,$role); } else { if ($role ne 'cc' && $env{'request.course.sec'} ne '') { if (&Apache::lonnet::allowed('c'.$role, $env{'request.course.id'}.'/'. $env{'request.course.sec'})) { push(@roles,$role); } } } } } else { @roles = @allroles; } } } return @roles; } sub curr_role_permissions { my ($context,$setting,$checkpriv) = @_; my $custom = 1; my @roles; if ($context eq 'author') { @roles = &construction_space_roles($checkpriv); } elsif ($context eq 'domain') { if ($setting eq 'course') { @roles = &course_roles($context,$checkpriv,$custom); } else { @roles = &domain_roles($checkpriv); } } elsif ($context eq 'course') { @roles = &course_roles($context,$checkpriv,$custom); } return @roles; } # ======================================================= Existing Custom Roles sub my_custom_roles { my %returnhash=(); my %rolehash=&Apache::lonnet::dump('roles'); foreach my $key (keys %rolehash) { if ($key=~/^rolesdef\_(\w+)$/) { $returnhash{$1}=$1; } } return %returnhash; } sub print_userlist { my ($r,$mode,$permission,$context,$formname,$totcodes,$codetitles, $idlist,$idlist_titles) = @_; my $format = $env{'form.output'}; if (! exists($env{'form.sortby'})) { $env{'form.sortby'} = 'username'; } if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) { $env{'form.Status'} = 'Active'; } my $status_select = &Apache::lonhtmlcommon::StatusOptions ($env{'form.Status'}); if ($env{'form.showrole'} eq '') { if ($context eq 'course') { $env{'form.showrole'} = 'st'; } else { $env{'form.showrole'} = 'Any'; } } if (! defined($env{'form.output'}) || $env{'form.output'} !~ /^(csv|excel|html)$/ ) { $env{'form.output'} = 'html'; } my @statuses; if ($env{'form.Status'} eq 'Any') { @statuses = ('previous','active','future'); } elsif ($env{'form.Status'} eq 'Expired') { @statuses = ('previous'); } elsif ($env{'form.Status'} eq 'Active') { @statuses = ('active'); } elsif ($env{'form.Status'} eq 'Future') { @statuses = ('future'); } # if ($context eq 'course') { # $r->print(&display_adv_courseroles()); # } # # Interface output $r->print('
'."\n". ''); $r->print("

\n"); if ($env{'form.action'} ne 'modifystudent') { my %lt=&Apache::lonlocal::texthash('csv' => "CSV", 'excel' => "Excel", 'html' => 'HTML'); my $output_selector = ''; $r->print(''.(' 'x3)); } $r->print(''.(' 'x3)."\n"); my $roleselected = ''; if ($env{'form.showrole'} eq 'Any') { $roleselected = ' selected="selected" '; } my ($cnum,$cdom); $r->print(&role_filter($context)); if ($context eq 'course') { ($cnum,$cdom) = &get_course_identity(); $r->print(§ion_group_filter($cnum,$cdom)); } if ($env{'form.phase'} eq '') { $r->print('

'.&list_submit_button(&mt('Display List of Users')). "\n

\n". '
'); return; } if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) { $r->print(' '.&list_submit_button(&mt('Update Display')). "\n

\n"); } my ($indexhash,$keylist) = &make_keylist_array(); my (%userlist,%userinfo); if ($context eq 'domain' && $env{'form.roletype'} eq 'course') { my $courseform = &Apache::lonhtmlcommon::course_selection($formname,$totcodes, $codetitles,$idlist,$idlist_titles); $r->print('

'.&Apache::lonhtmlcommon::start_pick_box()."\n". &Apache::lonhtmlcommon::start_pick_box()."\n". &Apache::lonhtmlcommon::row_title(&mt('Select Course(s)'), 'LC_oddrow_value')."\n". $courseform."\n". &Apache::lonhtmlcommon::row_closure(1). &Apache::lonhtmlcommon::end_pick_box().'

'. '

'.&list_submit_button(&mt('Update Display')). "\n".'

'.&mt('Warning: data retrieval for multiple courses can take considerable time, as this operation is not currently optimized.').''."\n"); if ($env{'form.coursepick'}) { $r->print('
'.&mt('Searching').' ...
 
'); } } else { $r->print('
'.&mt('Searching').' ...
 
'); } $r->rflush(); if ($context eq 'course') { if (($env{'form.showrole'} eq 'st') || ($env{'form.showrole'} eq 'Any')) { my $classlist = &Apache::loncoursedata::get_classlist(); if (ref($classlist) eq 'HASH') { %userlist = %{$classlist}; } } if ($env{'form.showrole'} ne 'st') { my $showroles; if ($env{'form.showrole'} ne 'Any') { $showroles = [$env{'form.showrole'}]; } else { $showroles = undef; } my $withsec = 1; my $hidepriv = 1; my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef, \@statuses,$showroles,undef,$withsec,$hidepriv); &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo, \%advrolehash,$permission); } } else { my (%cstr_roles,%dom_roles); if ($context eq 'author') { # List co-authors and assistant co-authors my @possroles = &roles_by_context($context); %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef, \@statuses,\@possroles); &gather_userinfo($context,$format,\%userlist,$indexhash,\%userinfo, \%cstr_roles,$permission); } elsif ($context eq 'domain') { if ($env{'form.roletype'} eq 'domain') { %dom_roles = &Apache::lonnet::get_domain_roles($env{'request.role.domain'}); foreach my $key (keys(%dom_roles)) { if (ref($dom_roles{$key}) eq 'HASH') { &gather_userinfo($context,$format,\%userlist,$indexhash, \%userinfo,$dom_roles{$key},$permission); } } } elsif ($env{'form.roletype'} eq 'author') { my %dom_roles = &Apache::lonnet::get_domain_roles($env{'request.role.domain'},['au']); my %coauthors; foreach my $key (keys(%dom_roles)) { if (ref($dom_roles{$key}) eq 'HASH') { if ($env{'form.showrole'} eq 'au') { &gather_userinfo($context,$format,\%userlist,$indexhash, \%userinfo,$dom_roles{$key},$permission); } else { my @possroles; if ($env{'form.showrole'} eq 'Any') { @possroles = &roles_by_context('author'); } else { @possroles = ($env{'form.showrole'}); } foreach my $author (sort(keys(%{$dom_roles{$key}}))) { my ($role,$authorname,$authordom) = split(/:/,$author,-1); my $extent = '/'.$authordom.'/'.$authorname; %{$coauthors{$extent}} = &Apache::lonnet::get_my_roles($authorname, $authordom,undef,\@statuses,\@possroles); } &gather_userinfo($context,$format,\%userlist, $indexhash,\%userinfo,\%coauthors,$permission); } } } } elsif ($env{'form.roletype'} eq 'course') { if ($env{'form.coursepick'}) { my %courses = &process_coursepick(); my %allusers; my $hidepriv = 1; foreach my $cid (keys(%courses)) { my ($cnum,$cdom,$cdesc) = &get_course_identity($cid); next if ($cnum eq '' || $cdom eq ''); my $custom = 1; my (@roles,@sections,%access,%users,%userdata, %statushash); if ($env{'form.showrole'} eq 'Any') { @roles = &course_roles($context,undef,$custom); } else { @roles = ($env{'form.showrole'}); } foreach my $role (@roles) { %{$users{$role}} = (); } foreach my $type (@statuses) { $access{$type} = $type; } &Apache::loncommon::get_course_users($cdom,$cnum,\%access,\@roles,\@sections,\%users,\%userdata,\%statushash,$hidepriv); foreach my $user (keys(%userdata)) { next if (ref($userinfo{$user}) eq 'HASH'); foreach my $item ('fullname','id') { $userinfo{$user}{$item} = $userdata{$user}[$indexhash->{$item}]; } } foreach my $role (keys(%users)) { foreach my $user (keys(%{$users{$role}})) { my $uniqid = $user.':'.$role; $allusers{$uniqid}{$cid} = { desc => $cdesc, secs => $statushash{$user}{$role}, }; } } } &gather_userinfo($context,$format,\%userlist,$indexhash, \%userinfo,\%allusers,$permission); } else { $r->print(''); return; } } } } if (keys(%userlist) == 0) { if ($context eq 'author') { $r->print(&mt('There are no co-authors to display.')."\n"); } elsif ($context eq 'domain') { if ($env{'form.roletype'} eq 'domain') { $r->print(&mt('There are no users with domain roles to display.')."\n"); } elsif ($env{'form.roletype'} eq 'author') { $r->print(&mt('There are no authors or co-authors to display.')."\n"); } elsif ($env{'form.roletype'} eq 'course') { $r->print(&mt('There are no course users to display')."\n"); } } elsif ($context eq 'course') { $r->print(&mt('There are no course users to display.')."\n"); } } else { # Print out the available choices my $usercount; if ($env{'form.action'} eq 'modifystudent') { ($usercount) = &show_users_list($r,$context,'view',$permission, $env{'form.Status'},\%userlist,$keylist); } else { ($usercount) = &show_users_list($r,$context,$env{'form.output'}, $permission,$env{'form.Status'},\%userlist,$keylist); } if (!$usercount) { $r->print('
' .&mt('There are no users matching the search criteria.') .'' ); } } $r->print(''); } sub role_filter { my ($context) = @_; my $output; my $roleselected = ''; if ($env{'form.showrole'} eq 'Any') { $roleselected = ' selected="selected" '; } my ($role_select); if ($context eq 'domain') { $role_select = &domain_roles_select(); $output = ''; } else { $role_select = ''; $output = ''; } return $output; } sub section_group_filter { my ($cnum,$cdom) = @_; my @filters; if ($env{'request.course.sec'} eq '') { @filters = ('sec'); } push(@filters,'grp'); my %name = ( sec => 'secfilter', grp => 'grpfilter', ); my %title = &Apache::lonlocal::texthash ( sec => 'Section(s)', grp => 'Group(s)', all => 'all', none => 'none', ); my $output; foreach my $item (@filters) { my ($markup,@options); if ($env{'form.'.$name{$item}} eq '') { $env{'form.'.$name{$item}} = 'all'; } if ($item eq 'sec') { if ($env{'form.showrole'} eq 'cc') { $env{'form.'.$name{$item}} = 'none'; } my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum); @options = sort(keys(%sections_count)); } elsif ($item eq 'grp') { my %curr_groups = &Apache::longroup::coursegroups(); @options = sort(keys(%curr_groups)); } if (@options > 0) { my $currsel; $markup = ''."\n"; $output .= (' 'x3).''; } } return $output; } sub list_submit_button { my ($text) = @_; return ''; } sub gather_userinfo { my ($context,$format,$userlist,$indexhash,$userinfo,$rolehash,$permission) = @_; my $viewablesec; if ($context eq 'course') { $viewablesec = &viewable_section($permission); } foreach my $item (keys(%{$rolehash})) { my %userdata; if ($context eq 'author') { ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) = split(/:/,$item); ($userdata{'start'},$userdata{'end'})=split(/:/,$rolehash->{$item}); &build_user_record($context,\%userdata,$userinfo,$indexhash, $item,$userlist); } elsif ($context eq 'course') { ($userdata{'username'},$userdata{'domain'},$userdata{'role'}, $userdata{'section'}) = split(/:/,$item,-1); ($userdata{'start'},$userdata{'end'})=split(/:/,$rolehash->{$item}); if (($viewablesec ne '') && ($userdata{'section'} ne '')) { next if ($viewablesec ne $userdata{'section'}); } &build_user_record($context,\%userdata,$userinfo,$indexhash, $item,$userlist); } elsif ($context eq 'domain') { if ($env{'form.roletype'} eq 'domain') { ($userdata{'role'},$userdata{'username'},$userdata{'domain'}) = split(/:/,$item); ($userdata{'end'},$userdata{'start'})=split(/:/,$rolehash->{$item}); &build_user_record($context,\%userdata,$userinfo,$indexhash, $item,$userlist); } elsif ($env{'form.roletype'} eq 'author') { if (ref($rolehash->{$item}) eq 'HASH') { $userdata{'extent'} = $item; foreach my $key (keys(%{$rolehash->{$item}})) { ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) = split(/:/,$key); ($userdata{'start'},$userdata{'end'}) = split(/:/,$rolehash->{$item}{$key}); my $uniqid = $key.':'.$item; &build_user_record($context,\%userdata,$userinfo, $indexhash,$uniqid,$userlist); } } } elsif ($env{'form.roletype'} eq 'course') { ($userdata{'username'},$userdata{'domain'},$userdata{'role'}) = split(/:/,$item); if (ref($rolehash->{$item}) eq 'HASH') { my $numcids = keys(%{$rolehash->{$item}}); foreach my $cid (sort(keys(%{$rolehash->{$item}}))) { if (ref($rolehash->{$item}{$cid}) eq 'HASH') { my $spanstart = ''; my $spanend = '; '; my $space = ', '; if ($format eq 'html' || $format eq 'view') { $spanstart = ''; # FIXME: actions on courses disabled for now # if ($permission->{'cusr'}) { # if ($numcids > 1) { # $spanstart .= ' '; # } else { # $spanstart .= ' '; # } # } $spanend = '
'; $space = ', '; } $userdata{'extent'} .= $spanstart. $rolehash->{$item}{$cid}{'desc'}.$space; if (ref($rolehash->{$item}{$cid}{'secs'}) eq 'HASH') { foreach my $sec (sort(keys(%{$rolehash->{$item}{$cid}{'secs'}}))) { if (($env{'form.Status'} eq 'Any') || ($env{'form.Status'} eq $rolehash->{$item}{$cid}{'secs'}{$sec})) { $userdata{'extent'} .= $sec.$space.$rolehash->{$item}{$cid}{'secs'}{$sec}.$spanend; $userdata{'status'} = $rolehash->{$item}{$cid}{'secs'}{$sec}; } } } } } } if ($userdata{'status'} ne '') { &build_user_record($context,\%userdata,$userinfo, $indexhash,$item,$userlist); } } } } return; } sub build_user_record { my ($context,$userdata,$userinfo,$indexhash,$record_key,$userlist) = @_; next if ($userdata->{'start'} eq '-1' && $userdata->{'end'} eq '-1'); if (!(($context eq 'domain') && ($env{'form.roletype'} eq 'course'))) { &process_date_info($userdata); } my $username = $userdata->{'username'}; my $domain = $userdata->{'domain'}; if (ref($userinfo->{$username.':'.$domain}) eq 'HASH') { $userdata->{'fullname'} = $userinfo->{$username.':'.$domain}{'fullname'}; $userdata->{'id'} = $userinfo->{$username.':'.$domain}{'id'}; } else { &aggregate_user_info($domain,$username,$userinfo); $userdata->{'fullname'} = $userinfo->{$username.':'.$domain}{'fullname'}; $userdata->{'id'} = $userinfo->{$username.':'.$domain}{'id'}; } foreach my $key (keys(%{$indexhash})) { if (defined($userdata->{$key})) { $userlist->{$record_key}[$indexhash->{$key}] = $userdata->{$key}; } } return; } sub courses_selector { my ($cdom,$formname) = @_; my %coursecodes = (); my %codes = (); my @codetitles = (); my %cat_titles = (); my %cat_order = (); my %idlist = (); my %idnums = (); my %idlist_titles = (); my $caller = 'global'; my $format_reply; my $jscript = ''; my $totcodes = 0; $totcodes = &Apache::courseclassifier::retrieve_instcodes(\%coursecodes, $cdom,$totcodes); if ($totcodes > 0) { $format_reply = &Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes, \%codes,\@codetitles,\%cat_titles,\%cat_order); if ($format_reply eq 'ok') { my $numtypes = @codetitles; &Apache::courseclassifier::build_code_selections(\%codes,\@codetitles,\%cat_titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles); my ($scripttext,$longtitles) = &Apache::courseclassifier::javascript_definitions(\@codetitles,\%idlist,\%idlist_titles,\%idnums,\%cat_titles); my $longtitles_str = join('","',@{$longtitles}); my $allidlist = $idlist{$codetitles[0]}; $jscript .= &Apache::courseclassifier::courseset_js_start($formname,$longtitles_str,$allidlist); $jscript .= $scripttext; $jscript .= &Apache::courseclassifier::javascript_code_selections($formname,@codetitles); } } my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($cdom); my %elements = ( Year => 'selectbox', coursepick => 'radio', coursetotal => 'text', courselist => 'text', ); $jscript .= &Apache::lonhtmlcommon::set_form_elements(\%elements); if ($env{'form.coursepick'} eq 'category') { $jscript .= qq| function setCourseCat(formname) { if (formname.Year.options[formname.Year.selectedIndex].value == -1) { return; } courseSet('Year'); for (var j=0; j 1) { my @course_ids = split(/&&/,$env{'form.courselist'}); foreach my $cid (@course_ids) { $courses{$cid} = ''; } } else { $courses{$env{'form.courselist'}} = ''; } } return %courses; } sub instcode_from_coursefilter { my $instcode = ''; my @cats = ('Semester','Year','Department','Number'); foreach my $category (@cats) { if (defined($env{'form.'.$category})) { unless ($env{'form.'.$category} eq '-1') { $instcode .= $env{'form.'.$category}; } } } if ($instcode eq '') { $instcode = '.'; } return $instcode; } sub display_adv_courseroles { my $output; # # List course personnel my %coursepersonnel = &Apache::lonnet::get_course_adv_roles($env{'request.course.id'}); # $output = '
'.&Apache::loncommon::start_data_table(); foreach my $role (sort(keys(%coursepersonnel))) { next if ($role =~ /^\s*$/); $output .= &Apache::loncommon::start_data_table_row(). ''.$role.''; foreach my $user (split(',',$coursepersonnel{$role})) { my ($puname,$pudom)=split(':',$user); $output .= ' '.&Apache::loncommon::aboutmewrapper( &Apache::loncommon::plainname($puname,$pudom), $puname,$pudom); } $output .= ''.&Apache::loncommon::end_data_table_row(); } $output .= &Apache::loncommon::end_data_table(); } sub make_keylist_array { my ($index,$keylist); $index->{'domain'} = &Apache::loncoursedata::CL_SDOM(); $index->{'username'} = &Apache::loncoursedata::CL_SNAME(); $index->{'end'} = &Apache::loncoursedata::CL_END(); $index->{'start'} = &Apache::loncoursedata::CL_START(); $index->{'id'} = &Apache::loncoursedata::CL_ID(); $index->{'section'} = &Apache::loncoursedata::CL_SECTION(); $index->{'fullname'} = &Apache::loncoursedata::CL_FULLNAME(); $index->{'status'} = &Apache::loncoursedata::CL_STATUS(); $index->{'type'} = &Apache::loncoursedata::CL_TYPE(); $index->{'lockedtype'} = &Apache::loncoursedata::CL_LOCKEDTYPE(); $index->{'groups'} = &Apache::loncoursedata::CL_GROUP(); $index->{'email'} = &Apache::loncoursedata::CL_PERMANENTEMAIL(); $index->{'role'} = &Apache::loncoursedata::CL_ROLE(); $index->{'extent'} = &Apache::loncoursedata::CL_EXTENT(); $index->{'photo'} = &Apache::loncoursedata::CL_PHOTO(); $index->{'thumbnail'} = &Apache::loncoursedata::CL_THUMBNAIL(); foreach my $key (keys(%{$index})) { $keylist->[$index->{$key}] = $key; } return ($index,$keylist); } sub aggregate_user_info { my ($udom,$uname,$userinfo) = @_; my %info=&Apache::lonnet::get('environment', ['firstname','middlename', 'lastname','generation','id'], $udom,$uname); my ($tmp) = keys(%info); my ($fullname,$id); if ($tmp =~/^(con_lost|error|no_such_host)/i) { $fullname = 'not available'; $id = 'not available'; &Apache::lonnet::logthis('unable to retrieve environment '. 'for '.$uname.':'.$udom); } else { $fullname = &Apache::lonnet::format_name(@info{qw/firstname middlename lastname generation/},'lastname'); $id = $info{'id'}; } $userinfo->{$uname.':'.$udom} = { fullname => $fullname, id => $id, }; return; } sub process_date_info { my ($userdata) = @_; my $now = time; $userdata->{'status'} = &mt('Active'); if ($userdata->{'start'} > 0) { if ($now < $userdata->{'start'}) { $userdata->{'status'} = &mt('Future'); } } if ($userdata->{'end'} > 0) { if ($now > $userdata->{'end'}) { $userdata->{'status'} = &mt('Expired'); } } return; } sub show_users_list { my ($r,$context,$mode,$permission,$statusmode,$userlist,$keylist,$formname)=@_; if ($formname eq '') { $formname = 'studentform'; } # # Variables for excel output my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format); # # Variables for csv output my ($CSVfile,$CSVfilename); # my $sortby = $env{'form.sortby'}; my @sortable = ('username','domain','id','fullname','start','end','email','role'); if ($context eq 'course') { push(@sortable,('section','groups','type')); } else { push(@sortable,'extent'); } if ($mode eq 'pickauthor') { @sortable = ('username','fullname','email','status'); } if (!grep(/^\Q$sortby\E$/,@sortable)) { $sortby = 'username'; } my $setting = $env{'form.roletype'}; my ($cid,$cdom,$cnum,$classgroups,$displayphotos,$displayclickers); if ($context eq 'course') { $cid = $env{'request.course.id'}; ($cnum,$cdom) = &get_course_identity($cid); ($classgroups) = &Apache::loncoursedata::get_group_memberships( $userlist,$keylist,$cdom,$cnum); if ($mode eq 'autoenroll') { $env{'form.showrole'} = 'st'; } else { if (! exists($env{'form.displayphotos'})) { $env{'form.displayphotos'} = 'off'; } $displayphotos = $env{'form.displayphotos'}; if (! exists($env{'form.displayclickers'})) { $env{'form.displayclickers'} = 'off'; } $displayclickers = $env{'form.displayclickers'}; if ($env{'course.'.$cid.'.internal.showphoto'}) { $r->print(' '); } $r->print(< END } } if ($mode ne 'autoenroll' && $mode ne 'pickauthor') { my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript(); my $date_sec_selector = &date_section_javascript($context,$setting,$statusmode); my $verify_action_js = &bulkaction_javascript($formname); $r->print(< $check_uncheck_js $verify_action_js function username_display_launch(username,domain) { var target; for (var i=0; i $date_sec_selector END } $r->print(< END my %lt=&Apache::lonlocal::texthash( 'username' => "username", 'domain' => "domain", 'id' => 'ID', 'fullname' => "name", 'section' => "section", 'groups' => "active groups", 'start' => "start date", 'end' => "end date", 'status' => "status", 'role' => "role", 'type' => "enroll type/action", 'email' => "e-mail address", 'photo' => "photo", 'extent' => "extent", 'pr' => "Proceed", 'ca' => "check all", 'ua' => "uncheck all", 'ac' => "Action to take for selected users", 'link' => "Behavior of clickable username link for each user", 'aboutme' => "Display a user's personal homepage", 'owin' => "Open in a new window", 'modify' => "Modify a user's information", 'clicker' => "Clicker-ID", ); if ($context eq 'domain' && $env{'form.roletype'} eq 'course') { $lt{'extent'} = &mt('Course(s): description, section(s), status'); } elsif ($context eq 'author') { $lt{'extent'} = &mt('Author'); } my @cols; if ($mode eq 'pickauthor') { @cols = ('username','fullname','status','email'); } else { @cols = ('username','domain','id','fullname'); if ($context eq 'course') { push(@cols,'section'); } if (!($context eq 'domain' && $env{'form.roletype'} eq 'course')) { push(@cols,('start','end')); } if ($env{'form.showrole'} eq 'Any' || $env{'form.showrole'} eq 'cr') { push(@cols,'role'); } if ($context eq 'domain' && ($env{'form.roletype'} eq 'author' || $env{'form.roletype'} eq 'course')) { push (@cols,'extent'); } if (($statusmode eq 'Any') && (!($context eq 'domain' && $env{'form.roletype'} eq 'course'))) { push(@cols,'status'); } if ($context eq 'course') { push(@cols,'groups'); } push(@cols,'email'); } my $rolefilter = $env{'form.showrole'}; if ($env{'form.showrole'} eq 'cr') { $rolefilter = &mt('custom'); } elsif ($env{'form.showrole'} ne 'Any') { $rolefilter = &Apache::lonnet::plaintext($env{'form.showrole'}); } my $results_description; if ($mode ne 'autoenroll') { $results_description = &results_header_row($rolefilter,$statusmode, $context,$permission,$mode); $r->print(''.$results_description.'

'); } my ($output,$actionselect,%canchange,%canchangesec); if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll' || $mode eq 'pickauthor') { if ($mode ne 'autoenroll' && $mode ne 'pickauthor') { if ($permission->{'cusr'}) { $actionselect = &select_actions($context,$setting,$statusmode,$formname); } $r->print(< END if ($actionselect) { $output .= <<"END";
$lt{'ac'} $actionselect

 
END my @allroles; if ($env{'form.showrole'} eq 'Any') { my $custom = 1; if ($context eq 'domain') { @allroles = &roles_by_context($setting,$custom); } else { @allroles = &roles_by_context($context,$custom); } } else { @allroles = ($env{'form.showrole'}); } foreach my $role (@allroles) { if ($context eq 'domain') { if ($setting eq 'domain') { if (&Apache::lonnet::allowed('c'.$role, $env{'request.role.domain'})) { $canchange{$role} = 1; } } elsif ($setting eq 'author') { if (&Apache::lonnet::allowed('c'.$role, $env{'request.role.domain'})) { $canchange{$role} = 1; } } } elsif ($context eq 'author') { if (&Apache::lonnet::allowed('c'.$role, $env{'user.domain'}.'/'.$env{'user.name'})) { $canchange{$role} = 1; } } elsif ($context eq 'course') { if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) { $canchange{$role} = 1; } elsif ($env{'request.course.sec'} ne '') { if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'}.'/'.$env{'request.course.sec'})) { $canchangesec{$role} = $env{'request.course.sec'}; } } } } } $output .= '
'.$lt{'link'}.''. ''; my @linkdests = ('aboutme'); if ($permission->{'cusr'}) { unshift (@linkdests,'modify'); } $output .= '
'; my $usernamelink = $env{'form.usernamelink'}; if ($usernamelink eq '') { $usernamelink = 'aboutme'; } foreach my $item (@linkdests) { my $checkedstr = ''; if ($item eq $usernamelink) { $checkedstr = ' checked="checked" '; } $output .= '
'; } my $checkwin; if ($env{'form.userwin'}) { $checkwin = 'checked = "checked"'; } $output .= '
'.$lt{'owin'}.'
'; } $output .= "\n".''."\n". &Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row(); if ($mode eq 'autoenroll') { $output .= " $lt{'type'} "; } else { if ($mode eq 'pickauthor') { $output .= "\n".' '."\n"; } else { $output .= "\n".''.&mt('Count').''."\n"; } if ($actionselect) { $output .= ''.&mt('Select').''."\n"; } } foreach my $item (@cols) { $output .= "$lt{$item}\n"; } my %role_types = &role_type_names(); if ($context eq 'course' && $mode ne 'autoenroll') { if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') { # Clicker display on or off? my %clicker_options = ( 'on' => 'Show', 'off' => 'Hide', ); my $clickerchg = 'on'; if ($displayclickers eq 'on') { $clickerchg = 'off'; } $output .= ' '."\n".' ' .&mt('[_1]'.$clicker_options{$clickerchg}.'[_2] clicker id' ,'' ,'') ."\n".' '."\n"; # Photo display on or off? if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { my %photo_options = &Apache::lonlocal::texthash( 'on' => 'Show', 'off' => 'Hide', ); my $photochg = 'on'; if ($displayphotos eq 'on') { $photochg = 'off'; } $output .= ' '."\n".' '. ''. $photo_options{$photochg}.' '.$lt{'photo'}."\n". ' '."\n"; } } } $output .= &Apache::loncommon::end_data_table_header_row(); # Done with the HTML header line } elsif ($mode eq 'csv') { # # Open a file $CSVfilename = '/prtspool/'. $env{'user.name'}.'_'.$env{'user.domain'}.'_'. time.'_'.rand(1000000000).'.csv'; unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) { $r->log_error("Couldn't open $CSVfilename for output $!"); $r->print(&mt('Problems occurred in writing the CSV file. ' .'This error has been logged. ' .'Please alert your LON-CAPA administrator.')); $CSVfile = undef; } # push @cols,'clicker'; # Write headers and data to file print $CSVfile '"'.$results_description.'"'."\n"; print $CSVfile '"'.join('","',map { &Apache::loncommon::csv_translate($lt{$_}) } (@cols))."\"\n"; } elsif ($mode eq 'excel') { push @cols,'clicker'; # Create the excel spreadsheet ($excel_workbook,$excel_filename,$format) = &Apache::loncommon::create_workbook($r); return if (! defined($excel_workbook)); $excel_sheet = $excel_workbook->addworksheet('userlist'); $excel_sheet->write($row++,0,$results_description,$format->{'h2'}); # my @colnames = map {$lt{$_}} (@cols); $excel_sheet->write($row++,0,\@colnames,$format->{'bold'}); } # Done with header lines in all formats my %index; my $i; foreach my $idx (@$keylist) { $index{$idx} = $i++; } my $usercount = 0; my ($secfilter,$grpfilter); if ($context eq 'course') { $secfilter = $env{'form.secfilter'}; $grpfilter = $env{'form.grpfilter'}; if ($secfilter eq '') { $secfilter = 'all'; } if ($grpfilter eq '') { $grpfilter = 'all'; } } # Get groups, role, permanent e-mail so we can sort on them if # necessary. foreach my $user (keys(%{$userlist})) { if ($user eq '' ) { delete($userlist->{$user}); next; } if ($context eq 'domain' && $user eq $env{'request.role.domain'}.'-domainconfig:'.$env{'request.role.domain'}) { delete($userlist->{$user}); next; } my ($uname,$udom,$role,$groups,$email); if (($statusmode ne 'Any') && ($userlist->{$user}->[$index{'status'}] ne $statusmode)) { delete($userlist->{$user}); next; } if ($context eq 'domain') { if ($env{'form.roletype'} eq 'domain') { ($role,$uname,$udom) = split(/:/,$user); if (($uname eq $env{'request.role.domain'}.'-domainconfig') && ($udom eq $env{'request.role.domain'})) { delete($userlist->{$user}); next; } } elsif ($env{'form.roletype'} eq 'author') { ($uname,$udom,$role) = split(/:/,$user,-1); } elsif ($env{'form.roletype'} eq 'course') { ($uname,$udom,$role) = split(/:/,$user); } } else { ($uname,$udom,$role) = split(/:/,$user,-1); if (($context eq 'course') && $role eq '') { $role = 'st'; } } $userlist->{$user}->[$index{'role'}] = $role; if (($env{'form.showrole'} ne 'Any') && (!($env{'form.showrole'} eq 'cr' && $role =~ /^cr\//)) && ($role ne $env{'form.showrole'})) { delete($userlist->{$user}); next; } if ($context eq 'course') { my @ac_groups; if (ref($classgroups) eq 'HASH') { $groups = $classgroups->{$user}; } if (ref($groups->{'active'}) eq 'HASH') { @ac_groups = keys(%{$groups->{'active'}}); $userlist->{$user}->[$index{'groups'}] = join(', ',@ac_groups); } if ($mode ne 'autoenroll') { my $section = $userlist->{$user}->[$index{'section'}]; if (($env{'request.course.sec'} ne '') && ($section ne $env{'request.course.sec'})) { if ($role eq 'st') { delete($userlist->{$user}); next; } } if ($secfilter eq 'none') { if ($section ne '') { delete($userlist->{$user}); next; } } elsif ($secfilter ne 'all') { if ($section ne $secfilter) { delete($userlist->{$user}); next; } } if ($grpfilter eq 'none') { if (@ac_groups > 0) { delete($userlist->{$user}); next; } } elsif ($grpfilter ne 'all') { if (!grep(/^\Q$grpfilter\E$/,@ac_groups)) { delete($userlist->{$user}); next; } } if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { if (($displayphotos eq 'on') && ($role eq 'st')) { $userlist->{$user}->[$index{'photo'}] = &Apache::lonnet::retrievestudentphoto($udom,$uname,'jpg'); $userlist->{$user}->[$index{'thumbnail'}] = &Apache::lonnet::retrievestudentphoto($udom,$uname, 'gif','thumbnail'); } } } } my %emails = &Apache::loncommon::getemails($uname,$udom); if ($emails{'permanentemail'} =~ /\S/) { $userlist->{$user}->[$index{'email'}] = $emails{'permanentemail'}; } $usercount ++; } my $autocount = 0; my $manualcount = 0; my $lockcount = 0; my $unlockcount = 0; if ($usercount) { $r->print($output); } else { if ($mode eq 'autoenroll') { return ($usercount,$autocount,$manualcount,$lockcount,$unlockcount); } else { return; } } # # Sort the users my $index = $index{$sortby}; my $second = $index{'username'}; my $third = $index{'domain'}; my @sorted_users = sort { lc($userlist->{$a}->[$index]) cmp lc($userlist->{$b}->[$index]) || lc($userlist->{$a}->[$second]) cmp lc($userlist->{$b}->[$second]) || lc($userlist->{$a}->[$third]) cmp lc($userlist->{$b}->[$third]) } (keys(%$userlist)); my $rowcount = 0; foreach my $user (@sorted_users) { my %in; my $sdata = $userlist->{$user}; $rowcount ++; foreach my $item (@{$keylist}) { $in{$item} = $sdata->[$index{$item}]; } my $clickers = (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1]; if ($clickers!~/\w/) { $clickers='-'; } $in{'clicker'} = $clickers; my $role = $in{'role'}; $in{'role'}=&Apache::lonnet::plaintext($sdata->[$index{'role'}]); if (! defined($in{'start'}) || $in{'start'} == 0) { $in{'start'} = &mt('none'); } else { $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'}); } if (! defined($in{'end'}) || $in{'end'} == 0) { $in{'end'} = &mt('none'); } else { $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'}); } if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') { $r->print(&Apache::loncommon::start_data_table_row()); my $checkval; if ($mode eq 'autoenroll') { my $cellentry; if ($in{'type'} eq 'auto') { $cellentry = ''.&mt('auto').' '; $autocount ++; } else { $cellentry = '
'.&mt('manual').'
'; $manualcount ++; if ($in{'lockedtype'}) { $cellentry .= ''; $unlockcount ++; } else { $cellentry .= ''; $lockcount ++; } $cellentry .= '
'; } $r->print("$cellentry\n"); } else { if ($mode ne 'pickauthor') { $r->print("$rowcount\n"); } if ($actionselect) { my $showcheckbox; if ($role =~ /^cr\//) { $showcheckbox = $canchange{'cr'}; } else { $showcheckbox = $canchange{$role}; } if (!$showcheckbox) { if ($context eq 'course') { if ($canchangesec{$role} ne '') { if ($canchangesec{$role} eq $in{'section'}) { $showcheckbox = 1; } } } } if ($showcheckbox) { $checkval = $user; if ($context eq 'course') { if ($role eq 'st') { $checkval .= ':st'; } $checkval .= ':'.$in{'section'}; if ($role eq 'st') { $checkval .= ':'.$in{'type'}.':'. $in{'lockedtype'}; } } $r->print(''); } else { $r->print(' '); } } elsif ($mode eq 'pickauthor') { $r->print(''); } } foreach my $item (@cols) { if ($item eq 'username') { $r->print(''.&print_username_link($mode,\%in).''); } elsif (($item eq 'start' || $item eq 'end') && ($actionselect)) { $r->print(''.$in{$item}.''."\n"); } else { $r->print(''.$in{$item}.''."\n"); } } if (($context eq 'course') && ($mode ne 'autoenroll')) { if ($env{'form.showrole'} eq 'st' || $env{'form.showrole'} eq 'Any') { if ($displayclickers eq 'on') { my $clickers = (&Apache::lonnet::userenvironment($in{'domain'},$in{'username'},'clickers'))[1]; if ($clickers!~/\w/) { $clickers='-'; } $r->print(''.$clickers.''); } else { $r->print('   '); } if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { if ($displayphotos eq 'on' && $role eq 'st' && $in{'photo'} ne '') { $r->print(' '); } else { $r->print('   '); } } } } $r->print(&Apache::loncommon::end_data_table_row()); } elsif ($mode eq 'csv') { next if (! defined($CSVfile)); # no need to bother with $linkto if (! defined($in{'start'}) || $in{'start'} == 0) { $in{'start'} = &mt('none'); } else { $in{'start'} = &Apache::lonlocal::locallocaltime($in{'start'}); } if (! defined($in{'end'}) || $in{'end'} == 0) { $in{'end'} = &mt('none'); } else { $in{'end'} = &Apache::lonlocal::locallocaltime($in{'end'}); } my @line = (); foreach my $item (@cols) { push @line,&Apache::loncommon::csv_translate($in{$item}); } print $CSVfile '"'.join('","',@line)."\"\n"; } elsif ($mode eq 'excel') { my $col = 0; foreach my $item (@cols) { if ($item eq 'start' || $item eq 'end') { if (defined($item) && $item != 0) { $excel_sheet->write($row,$col++, &Apache::lonstathelpers::calc_serial($in{item}), $format->{'date'}); } else { $excel_sheet->write($row,$col++,'none'); } } else { $excel_sheet->write($row,$col++,$in{$item}); } } $row++; } } if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll' || $mode eq 'pickauthor') { $r->print(&Apache::loncommon::end_data_table().'
'); } elsif ($mode eq 'excel') { $excel_workbook->close(); $r->print(&mt('[_1]Your Excel spreadsheet[_2] is ready for download.', '

','')."

\n"); } elsif ($mode eq 'csv') { close($CSVfile); $r->print(&mt('[_1]Your CSV file[_2] is ready for download.', '

','')."

\n"); $r->rflush(); } if ($mode eq 'autoenroll') { return ($usercount,$autocount,$manualcount,$lockcount,$unlockcount); } else { return ($usercount); } } sub bulkaction_javascript { my ($formname,$caller) = @_; my $docstart = 'document'; if ($caller eq 'popup') { $docstart = 'opener.document'; } my %lt = &Apache::lonlocal::texthash( acwi => 'Access will be set to start immediately', asyo => 'as you did not select an end date in the pop-up window', accw => 'Access will be set to continue indefinitely', asyd => 'as you did not select an end date in the pop-up window', sewi => "Sections will be switched to 'No section'", ayes => "as you either selected the 'No section' option", oryo => 'or you did not select a section in the pop-up window', arol => 'A role with no section will be added', swbs => 'Sections will be switched to:', rwba => 'Roles will be added for section(s):', ); my $alert = &mt("You must select at least one user by checking a user's 'Select' checkbox"); my $noaction = &mt("You need to select an action to take for the user(s) you have selected"); my $singconfirm = &mt(' for a single user?'); my $multconfirm = &mt(' for multiple users?'); my $output = <<"ENDJS"; function verify_action (field) { var numchecked = 0; var singconf = '$singconfirm'; var multconf = '$multconfirm'; if ($docstart.$formname.elements[field].length > 0) { for (i=0; i<$docstart.$formname.elements[field].length; i++) { if ($docstart.$formname.elements[field][i].checked == true) { numchecked ++; } } } else { if ($docstart.$formname.elements[field].checked == true) { numchecked ++; } } if (numchecked == 0) { alert("$alert"); return; } else { var message = $docstart.$formname.bulkaction[$docstart.$formname.bulkaction.selectedIndex].text; var choice = $docstart.$formname.bulkaction[$docstart.$formname.bulkaction.selectedIndex].value; if (choice == '') { alert("$noaction"); return; } else { if (numchecked == 1) { message += singconf; } else { message += multconf; } ENDJS if ($caller ne 'popup') { $output .= <<"NEWWIN"; if (choice == 'chgdates' || choice == 'reenable' || choice == 'activate' || choice == 'chgsec') { opendatebrowser(document.$formname,'$formname','go'); return; } else { if (confirm(message)) { document.$formname.phase.value = 'bulkchange'; document.$formname.submit(); return; } } NEWWIN } else { $output .= <<"POPUP"; if (choice == 'chgdates' || choice == 'reenable' || choice == 'activate') { var datemsg = ''; if (($docstart.$formname.startdate_month.value == '') && ($docstart.$formname.startdate_day.value == '') && ($docstart.$formname.startdate_year.value == '')) { datemsg = "\\n$lt{'acwi'},\\n$lt{'asyo'}.\\n"; } if (($docstart.$formname.enddate_month.value == '') && ($docstart.$formname.enddate_day.value == '') && ($docstart.$formname.enddate_year.value == '')) { datemsg += "\\n$lt{'accw'},\\n$lt{'asyd'}.\\n"; } if (datemsg != '') { message += "\\n"+datemsg; } } if (choice == 'chgsec') { var rolefilter = $docstart.$formname.showrole.options[$docstart.$formname.showrole.selectedIndex].value; var retained = $docstart.$formname.retainsec.value; var secshow = $docstart.$formname.newsecs.value; if (secshow == '') { if (rolefilter == 'st' || retained == 0 || retained == "") { message += "\\n\\n$lt{'sewi'},\\n$lt{'ayes'},\\n$lt{'oryo'}.\\n"; } else { message += "\\n\\n$lt{'arol'}\\n$lt{'ayes'},\\n$lt{'oryo'}.\\n"; } } else { if (rolefilter == 'st' || retained == 0 || retained == "") { message += "\\n\\n$lt{'swbs'} "+secshow+".\\n"; } else { message += "\\n\\n$lt{'rwba'} "+secshow+".\\n"; } } } if (confirm(message)) { $docstart.$formname.phase.value = 'bulkchange'; $docstart.$formname.submit(); window.close(); } POPUP } $output .= ' } } } '; return $output; } sub print_username_link { my ($mode,$in) = @_; my $output; if ($mode eq 'autoenroll') { $output = $in->{'username'}; } else { $output = '{'username'}','$in->{'domain'}'".')" />'. $in->{'username'}.''; } return $output; } sub role_type_names { my %lt = &Apache::lonlocal::texthash ( 'domain' => 'Domain Roles', 'author' => 'Co-Author Roles', 'course' => 'Course Roles', ); return %lt; } sub select_actions { my ($context,$setting,$statusmode,$formname) = @_; my %lt = &Apache::lonlocal::texthash( revoke => "Revoke user roles", delete => "Delete user roles", reenable => "Re-enable expired user roles", activate => "Make future user roles active now", chgdates => "Change starting/ending dates", chgsec => "Change section associated with user roles", ); my ($output,$options,%choices); # FIXME Disable actions for now for roletype=course in domain context if ($context eq 'domain' && $setting eq 'course') { return; } if ($context eq 'course') { if ($env{'form.showrole'} ne 'Any') { if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'}, $env{'request.course.id'})) { if ($env{'request.course.sec'} eq '') { return; } else { if (!&Apache::lonnet::allowed('c'.$env{'form.showrole'},$env{'request.course.id'}.'/'.$env{'request.course.sec'})) { return; } } } } } if ($statusmode eq 'Any') { $options .= ' '; $choices{'dates'} = 1; } else { if ($statusmode eq 'Future') { $options .= ' '; $choices{'dates'} = 1; } elsif ($statusmode eq 'Expired') { $options .= ' '; $choices{'dates'} = 1; } if ($statusmode eq 'Active' || $statusmode eq 'Future') { $options .= ' '; $choices{'dates'} = 1; } } if ($context eq 'domain') { $options .= ' '; } if (($context eq 'course') || ($context eq 'domain' && $setting eq 'course')) { if (($statusmode ne 'Expired') && ($env{'request.course.sec'} eq '')) { $options .= ' '; $choices{'sections'} = 1; } } if ($options) { $output = ''; if ($choices{'dates'}) { $output .= ''."\n". ''."\n". ''."\n". ''."\n". ''."\n". ''."\n". ''."\n". ''."\n". ''."\n". ''."\n". ''."\n". ''."\n". ''."\n"; if ($context eq 'course') { $output .= ''."\n"; } } if ($choices{'sections'}) { $output .= ''."\n". ''."\n"; } } return $output; } sub date_section_javascript { my ($context,$setting) = @_; my $title = 'Date_And_Section_Selector'; my %nopopup = &Apache::lonlocal::texthash ( revoke => "Check the boxes for any users for whom roles are to be revoked, and click 'Proceed'", delete => "Check the boxes for any users for whom roles are to be deleted, and click 'Proceed'", none => "Choose an action to take for selected users", ); my $output = ' ENDTWO return $output; } sub date_section_selector { my ($context,$permission) = @_; my $callingform = $env{'form.callingform'}; my $formname = 'dateselect'; my $groupslist = &get_groupslist(); my $sec_js = &setsections_javascript($formname,$groupslist); my $output = <<"END"; ENDJS my %lt = &Apache::lonlocal::texthash ( chac => 'Access dates to apply for selected users', chse => 'Changes in section affiliation to apply to selected users', fors => 'For student roles changing the section, will result in a section switch as students may only be in one section of a course at a time.', forn => 'For a role in a course that is not a student role, a user may have roles in more than one section of a course at a time.', reta => "Retain each user's current section affiliations?", dnap => '(Does not apply to student roles).', ); my ($date_items,$headertext); if ($env{'form.bulkaction'} eq 'chgsec') { $headertext = $lt{'chse'}; } else { $headertext = $lt{'chac'}; my $starttime; if (($env{'form.bulkaction'} eq 'activate') || ($env{'form.bulkaction'} eq 'reenable')) { $starttime = time; } $date_items = &date_setting_table($starttime,undef,$context, $env{'form.bulkaction'},$formname, $permission); } $output .= '

'.$headertext.'

'. '
'."\n". $date_items; if ($context eq 'course' && $env{'form.bulkaction'} eq 'chgsec') { my ($cnum,$cdom) = &get_course_identity(); my $info; if ($env{'form.showrole'} eq 'st') { $output .= '

'.$lt{'fors'}.'

'; } elsif ($env{'form.showrole'} eq 'Any') { $output .= '

'.$lt{'fors'}.'

'. '

'.$lt{'forn'}.' '; $info = $lt{'reta'}; } else { $output .= '

'.$lt{'forn'}.' '; $info = $lt{'reta'}; } if ($info) { $info .= ''. '  '. ''; if ($env{'form.showrole'} eq 'Any') { $info .= '
'.$lt{'dnap'}; } $info .= '

'; } else { $info = ''; } my $rowtitle = &mt('New section to assign'); my $secbox = §ion_picker($cdom,$cnum,$env{'form.showrole'},$rowtitle,$permission,$context); $output .= $info.$secbox; } $output .= '

'. '

'."\n". '
'; return $output; } sub section_picker { my ($cdom,$cnum,$role,$rowtitle,$permission,$context,$mode) = @_; my %sections_count = &Apache::loncommon::get_sections($cdom,$cnum); my $sections_select .= &course_sections(\%sections_count,$role); my $secbox = '

'.&Apache::lonhtmlcommon::start_pick_box()."\n"; if ($mode eq 'upload') { my ($options,$cb_script,$coursepick) = &default_role_selector($context,1); $secbox .= &Apache::lonhtmlcommon::row_title(&mt('role'),'LC_oddrow_value'). $options. &Apache::lonhtmlcommon::row_closure(1)."\n"; } $secbox .= &Apache::lonhtmlcommon::row_title($rowtitle,'LC_oddrow_value')."\n"; if ($env{'request.course.sec'} eq '') { $secbox .= ''."\n". '
'.&mt('Existing sections')."\n". '
'.$sections_select.'
'. &mt('New section').'
'."\n". ''."\n". ''."\n". '
'."\n"; } else { $secbox .= ''. $env{'request.course.sec'}; } $secbox .= &Apache::lonhtmlcommon::row_closure(1)."\n". &Apache::lonhtmlcommon::end_pick_box().'

'; return $secbox; } sub results_header_row { my ($rolefilter,$statusmode,$context,$permission,$mode) = @_; my ($description,$showfilter); if ($rolefilter ne 'Any') { $showfilter = $rolefilter; } if ($context eq 'course') { if ($mode eq 'csv' || $mode eq 'excel') { $description = &mt('Course - [_1]:',$env{'course.'.$env{'request.course.id'}.'.description'}).' '; } if ($statusmode eq 'Expired') { $description .= &mt('Users in course with expired [_1] roles',$showfilter); } elsif ($statusmode eq 'Future') { $description .= &mt('Users in course with future [_1] roles',$showfilter); } elsif ($statusmode eq 'Active') { $description .= &mt('Users in course with active [_1] roles',$showfilter); } else { if ($rolefilter eq 'Any') { $description .= &mt('All users in course'); } else { $description .= &mt('All users in course with [_1] roles',$rolefilter); } } my $constraint; my $viewablesec = &viewable_section($permission); if ($viewablesec ne '') { if ($env{'form.showrole'} eq 'st') { $constraint = &mt('only users in section "[_1]"',$viewablesec); } elsif ($env{'form.showrole'} ne 'cc') { $constraint = &mt('only users affiliated with no section or section "[_1]"',$viewablesec); } if (($env{'form.grpfilter'} ne 'all') && ($env{'form.grpfilter'} ne '')) { if ($env{'form.grpfilter'} eq 'none') { $constraint .= &mt(' and not in any group'); } else { $constraint .= &mt(' and members of group: "[_1]"',$env{'form.grpfilter'}); } } } else { if (($env{'form.secfilter'} ne 'all') && ($env{'form.secfilter'} ne '')) { if ($env{'form.secfilter'} eq 'none') { $constraint = &mt('only users affiliated with no section'); } else { $constraint = &mt('only users affiliated with section "[_1]"',$env{'form.secfilter'}); } } if (($env{'form.grpfilter'} ne 'all') && ($env{'form.grpfilter'} ne '')) { if ($env{'form.grpfilter'} eq 'none') { if ($constraint eq '') { $constraint = &mt('only users not in any group'); } else { $constraint .= &mt(' and also not in any group'); } } else { if ($constraint eq '') { $constraint = &mt('only members of group: "[_1]"',$env{'form.grpfilter'}); } else { $constraint .= &mt(' and also members of group: "[_1]"'.$env{'form.grpfilter'}); } } } } if ($constraint ne '') { $description .= ' ('.$constraint.')'; } } elsif ($context eq 'author') { $description = &mt('Author space for [_1]' ,'' .&Apache::loncommon::plainname($env{'user.name'},$env{'user.domain'}) .'') .':  '; if ($statusmode eq 'Expired') { $description .= &mt('Co-authors with expired [_1] roles',$showfilter); } elsif ($statusmode eq 'Future') { $description .= &mt('Co-authors with future [_1] roles',$showfilter); } elsif ($statusmode eq 'Active') { $description .= &mt('Co-authors with active [_1] roles',$showfilter); } else { if ($rolefilter eq 'Any') { $description .= &mt('All co-authors'); } else { $description .= &mt('All co-authors with [_1] roles',$rolefilter); } } } elsif ($context eq 'domain') { my $domdesc = &Apache::lonnet::domain($env{'request.role.domain'},'description'); $description = &mt('Domain - [_1]:',$domdesc).' '; if ($env{'form.roletype'} eq 'domain') { if ($statusmode eq 'Expired') { $description .= &mt('Users in domain with expired [_1] roles',$showfilter); } elsif ($statusmode eq 'Future') { $description .= &mt('Users in domain with future [_1] roles',$showfilter); } elsif ($statusmode eq 'Active') { $description .= &mt('Users in domain with active [_1] roles',$showfilter); } else { if ($rolefilter eq 'Any') { $description .= &mt('All users in domain'); } else { $description .= &mt('All users in domain with [_1] roles',$rolefilter); } } } elsif ($env{'form.roletype'} eq 'author') { if ($statusmode eq 'Expired') { $description .= &mt('Co-authors in domain with expired [_1] roles',$showfilter); } elsif ($statusmode eq 'Future') { $description .= &mt('Co-authors in domain with future [_1] roles',$showfilter); } elsif ($statusmode eq 'Active') { $description .= &mt('Co-authors in domain with active [_1] roles',$showfilter); } else { if ($rolefilter eq 'Any') { $description .= &mt('All users with co-author roles in domain',$showfilter); } else { $description .= &mt('All co-authors in domain with [_1] roles',$rolefilter); } } } elsif ($env{'form.roletype'} eq 'course') { my $coursefilter = $env{'form.coursepick'}; if ($coursefilter eq 'category') { my $instcode = &instcode_from_coursefilter(); if ($instcode eq '.') { $description .= &mt('All courses in domain').' - '; } else { $description .= &mt('Courses in domain with institutional code: [_1]',$instcode).' - '; } } elsif ($coursefilter eq 'selected') { $description .= &mt('Selected courses in domain').' - '; } elsif ($coursefilter eq 'all') { $description .= &mt('All courses in domain').' - '; } if ($statusmode eq 'Expired') { $description .= &mt('users with expired [_1] roles',$showfilter); } elsif ($statusmode eq 'Future') { $description .= &mt('users with future [_1] roles',$showfilter); } elsif ($statusmode eq 'Active') { $description .= &mt('users with active [_1] roles',$showfilter); } else { if ($rolefilter eq 'Any') { $description .= &mt('all users'); } else { $description .= &mt('users with [_1] roles',$rolefilter); } } } } return $description; } sub viewable_section { my ($permission) = @_; my $viewablesec; if (ref($permission) eq 'HASH') { if (exists($permission->{'view_section'})) { $viewablesec = $permission->{'view_section'}; } elsif (exists($permission->{'cusr_section'})) { $viewablesec = $permission->{'cusr_section'}; } } return $viewablesec; } ################################################# ################################################# sub show_drop_list { my ($r,$classlist,$nosort,$permission) = @_; my $cid = $env{'request.course.id'}; my ($cnum,$cdom) = &get_course_identity($cid); if (! exists($env{'form.sortby'})) { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['sortby']); } my $sortby = $env{'form.sortby'}; if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) { $sortby = 'username'; } my $action = "drop"; my $check_uncheck_js = &Apache::loncommon::check_uncheck_jscript(); $r->print(<

END my ($indexhash,$keylist) = &make_keylist_array(); my $studentcount = 0; if (ref($classlist) eq 'HASH') { foreach my $student (keys(%{$classlist})) { my $sdata = $classlist->{$student}; my $status = $sdata->[$indexhash->{'status'}]; my $section = $sdata->[$indexhash->{'section'}]; if ($status ne 'Active') { delete($classlist->{$student}); next; } if ($env{'request.course.sec'} ne '') { if ($section ne $env{'request.course.sec'}) { delete($classlist->{$student}); next; } } $studentcount ++; } } if (!$studentcount) { $r->print(&mt('There are no students to drop.')); return; } my ($classgroups) = &Apache::loncoursedata::get_group_memberships( $classlist,$keylist,$cdom,$cnum); my %lt=&Apache::lonlocal::texthash('usrn' => "username", 'dom' => "domain", 'sn' => "student name", 'sec' => "section", 'start' => "start date", 'end' => "end date", 'groups' => "active groups", ); if ($nosort) { $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row()); $r->print(<  $lt{'usrn'} $lt{'dom'} ID $lt{'sn'} $lt{'sec'} $lt{'start'} $lt{'end'} $lt{'groups'} END $r->print(&Apache::loncommon::end_data_table_header_row()); } else { $r->print(&Apache::loncommon::start_data_table(). &Apache::loncommon::start_data_table_header_row()); $r->print(<  $lt{'usrn'} $lt{'dom'} ID $lt{'sn'} $lt{'sec'} $lt{'start'} $lt{'end'} $lt{'groups'} END $r->print(&Apache::loncommon::end_data_table_header_row()); } # # Sort the students my $index = $indexhash->{$sortby}; my $second = $indexhash->{'username'}; my $third = $indexhash->{'domain'}; my @Sorted_Students = sort { lc($classlist->{$a}->[$index]) cmp lc($classlist->{$b}->[$index]) || lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second]) || lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third]) } (keys(%{$classlist})); foreach my $student (@Sorted_Students) { my $error; my $sdata = $classlist->{$student}; my $username = $sdata->[$indexhash->{'username'}]; my $domain = $sdata->[$indexhash->{'domain'}]; my $section = $sdata->[$indexhash->{'section'}]; my $name = $sdata->[$indexhash->{'fullname'}]; my $id = $sdata->[$indexhash->{'id'}]; my $start = $sdata->[$indexhash->{'start'}]; my $end = $sdata->[$indexhash->{'end'}]; my $groups = $classgroups->{$student}; my $active_groups; if (ref($groups->{active}) eq 'HASH') { $active_groups = join(', ',keys(%{$groups->{'active'}})); } if (! defined($start) || $start == 0) { $start = &mt('none'); } else { $start = &Apache::lonlocal::locallocaltime($start); } if (! defined($end) || $end == 0) { $end = &mt('none'); } else { $end = &Apache::lonlocal::locallocaltime($end); } my $studentkey = $student.':'.$section; my $startitem = ''; # $r->print(&Apache::loncommon::start_data_table_row()); $r->print(<<"END"); $username $domain $id $name $section $start $startitem $end $active_groups END $r->print(&Apache::loncommon::end_data_table_row()); } $r->print(&Apache::loncommon::end_data_table().'
'); %lt=&Apache::lonlocal::texthash( 'dp' => "Drop Students", 'ca' => "check all", 'ua' => "uncheck all", ); $r->print(<<"END");

 

END return; } # # Print out the initial form to get the file containing a list of users # sub print_first_users_upload_form { my ($r,$context) = @_; my $str; $str = ''; $str .= ''; $str .= ''; $str .= "

".&mt('Upload a file containing information about users')."

\n"; $str .= &Apache::loncommon::upfile_select_html(); $str .= '

'; $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List", &mt("How do I create a users list from a spreadsheet")). "
\n"; $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV", &mt("How do I create a CSV file from a spreadsheet")); $str .= "

\n"; $str .= "

\n"; $str .= '

\n"; $str .= ''."
\n"; $str .= &Apache::loncommon::end_page(); $r->print($str); return; } # ================================================= Drop/Add from uploaded file sub upfile_drop_add { my ($r,$context,$permission) = @_; &Apache::loncommon::load_tmp_file($r); my @userdata=&Apache::loncommon::upfile_record_sep(); if($env{'form.noFirstLine'}){shift(@userdata);} my @keyfields = split(/\,/,$env{'form.keyfields'}); my %fields=(); for (my $i=0; $i<=$env{'form.nfields'}; $i++) { if ($env{'form.upfile_associate'} eq 'reverse') { if ($env{'form.f'.$i} ne 'none') { $fields{$keyfields[$i]}=$env{'form.f'.$i}; } } else { $fields{$env{'form.f'.$i}}=$keyfields[$i]; } } if ($env{'form.fullup'} ne 'yes') { $r->print('
'."\n". ''); } # # Store the field choices away foreach my $field (qw/username names fname mname lname gen id sec ipwd email role domain/) { $env{'form.'.$field.'_choice'}=$fields{$field}; } &Apache::loncommon::store_course_settings('enrollment_upload', { 'username_choice' => 'scalar', 'names_choice' => 'scalar', 'fname_choice' => 'scalar', 'mname_choice' => 'scalar', 'lname_choice' => 'scalar', 'gen_choice' => 'scalar', 'id_choice' => 'scalar', 'sec_choice' => 'scalar', 'ipwd_choice' => 'scalar', 'email_choice' => 'scalar', 'role_choice' => 'scalar', 'domain_choice' => 'scalar'}); # my ($startdate,$enddate) = &get_dates_from_form(); if ($env{'form.makedatesdefault'}) { $r->print(&make_dates_default($startdate,$enddate,$context)); } # Determine domain and desired host (home server) my $defdom=$env{'request.role.domain'}; my $domain; if ($env{'form.defaultdomain'} ne '') { $domain = $env{'form.defaultdomain'}; } else { $domain = $defdom; } my $desiredhost = $env{'form.lcserver'}; if (lc($desiredhost) eq 'default') { $desiredhost = undef; } else { my %home_servers = &Apache::lonnet::get_servers($defdom,'library'); if (! exists($home_servers{$desiredhost})) { $r->print(''.&mt('Error'). &mt('Invalid home server specified').''); $r->print(&Apache::loncommon::end_page()); return; } } # Determine authentication mechanism my $changeauth; if ($context eq 'domain') { $changeauth = $env{'form.changeauth'}; } my $amode = ''; my $genpwd = ''; if ($env{'form.login'} eq 'krb') { $amode='krb'; $amode.=$env{'form.krbver'}; $genpwd=$env{'form.krbarg'}; } elsif ($env{'form.login'} eq 'int') { $amode='internal'; if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) { $genpwd=$env{'form.intarg'}; } } elsif ($env{'form.login'} eq 'loc') { $amode='localauth'; if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) { $genpwd=$env{'form.locarg'}; } } if ($amode =~ /^krb/) { if (! defined($genpwd) || $genpwd eq '') { $r->print(''. &mt('Unable to enroll users').' '. &mt('No Kerberos domain was specified.').'

'); $amode = ''; # This causes the loop below to be skipped } } my ($cid,$defaultsec,$defaultrole,$setting); if ($context eq 'domain') { $setting = $env{'form.roleaction'}; if ($setting eq 'domain') { $defaultrole = $env{'form.defaultrole'}; } elsif ($setting eq 'course') { $defaultrole = $env{'form.courserole'}; $defaultsec = $env{'form.sections'}; } } elsif ($context eq 'author') { $defaultrole = $env{'form.defaultrole'}; } elsif ($context eq 'course') { $defaultrole = $env{'form.defaultrole'}; $defaultsec = $env{'form.sections'}; } if ($env{'request.course.id'} ne '') { $cid = $env{'request.course.id'}; } elsif ($setting eq 'course') { if (&Apache::lonnet::is_course($env{'form.dcdomain'},$env{'form.dccourse'})) { $cid = $env{'form.dcdomain'}.'_'.$env{'form.dccourse'}; } } # Check to see if user information can be changed my @userinfo = ('firstname','middlename','lastname','generation', 'permanentemail','id'); my %canmodify; if (&Apache::lonnet::allowed('mau',$domain)) { foreach my $field (@userinfo) { $canmodify{$field} = 1; } } my (%userlist,%modifiable_fields,@poss_roles); my $secidx = &Apache::loncoursedata::CL_SECTION(); my @courseroles = &roles_by_context('course',1); if (!&Apache::lonnet::allowed('mau',$domain)) { if ($context eq 'course' || $context eq 'author') { @poss_roles = &curr_role_permissions($context); my @statuses = ('active','future'); my ($indexhash,$keylist) = &make_keylist_array(); my %info; foreach my $role (@poss_roles) { %{$modifiable_fields{$role}} = &can_modify_userinfo($context,$domain, \@userinfo,[$role]); } if ($context eq 'course') { my ($cnum,$cdom) = &get_course_identity(); my $roster = &Apache::loncoursedata::get_classlist(); if (ref($roster) eq 'HASH') { %userlist = %{$roster}; } my %advrolehash = &Apache::lonnet::get_my_roles($cnum,$cdom,undef, \@statuses,\@poss_roles); &gather_userinfo($context,'view',\%userlist,$indexhash,\%info, \%advrolehash,$permission); } elsif ($context eq 'author') { my %cstr_roles = &Apache::lonnet::get_my_roles(undef,undef,undef, \@statuses,\@poss_roles); &gather_userinfo($context,'view',\%userlist,$indexhash,\%info, \%cstr_roles,$permission); } } } if ( $domain eq &LONCAPA::clean_domain($domain) && ($amode ne '')) { ####################################### ## Add/Modify Users ## ####################################### if ($context eq 'course') { $r->print('

'.&mt('Enrolling Users')."

\n

\n"); } elsif ($context eq 'author') { $r->print('

'.&mt('Updating Co-authors')."

\n

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

'.&mt('Adding/Modifying Users')."

\n

\n"); } my %counts = ( user => 0, auth => 0, role => 0, ); my $flushc=0; my %student=(); my (%curr_groups,@sections,@cleansec,$defaultwarn,$groupwarn); my %userchg; if ($context eq 'course' || $setting eq 'course') { if ($context eq 'course') { # Get information about course groups %curr_groups = &Apache::longroup::coursegroups(); } elsif ($setting eq 'course') { if ($cid) { %curr_groups = &Apache::longroup::coursegroups($env{'form.dcdomain'}, $env{'form.dccourse'}); } } # determine section number if ($defaultsec =~ /,/) { push(@sections,split(/,/,$defaultsec)); } else { push(@sections,$defaultsec); } # remove non alphanumeric values from section foreach my $item (@sections) { $item =~ s/\W//g; if ($item eq "none" || $item eq 'all') { $defaultwarn = &mt('Default section name [_1] could not be used as it is a reserved word.',$item); } elsif ($item ne '' && exists($curr_groups{$item})) { $groupwarn = &mt('Default section name "[_1]" is the name of a course group. Section names and group names must be distinct.',$item); } elsif ($item ne '') { push(@cleansec,$item); } } if ($defaultwarn) { $r->print($defaultwarn.'
'); } if ($groupwarn) { $r->print($groupwarn.'
'); } } my (%curr_rules,%got_rules,%alerts); my %customroles = &my_custom_roles(); my @permitted_roles = &roles_on_upload($context,$setting,%customroles); # Get new users list foreach my $line (@userdata) { my @secs; my %entries=&Apache::loncommon::record_sep($line); # Determine user name unless (($entries{$fields{'username'}} eq '') || (!defined($entries{$fields{'username'}}))) { my ($fname, $mname, $lname,$gen) = ('','','',''); if (defined($fields{'names'})) { ($lname,$fname,$mname)=($entries{$fields{'names'}}=~ /([^\,]+)\,\s*(\w+)\s*(.*)$/); } else { if (defined($fields{'fname'})) { $fname=$entries{$fields{'fname'}}; } if (defined($fields{'mname'})) { $mname=$entries{$fields{'mname'}}; } if (defined($fields{'lname'})) { $lname=$entries{$fields{'lname'}}; } if (defined($fields{'gen'})) { $gen=$entries{$fields{'gen'}}; } } if ($entries{$fields{'username'}} ne &LONCAPA::clean_username($entries{$fields{'username'}})) { $r->print('
'. &mt('[_1]: Unacceptable username for user [_2] [_3] [_4] [_5]', ''.$entries{$fields{'username'}}.'',$fname,$mname,$lname,$gen)); next; } else { if ($entries{$fields{'domain'}} ne &LONCAPA::clean_domain($entries{$fields{'domain'}})) { $r->print('
'. ''.$entries{$fields{'domain'}}. ': '.&mt('Unacceptable domain for user [_2] [_3] [_4] [_5]',$fname,$mname,$lname,$gen)); next; } my $username = $entries{$fields{'username'}}; my $userdomain = $entries{$fields{'domain'}}; if ($userdomain eq '') { $userdomain = $domain; } if (defined($fields{'sec'})) { if (defined($entries{$fields{'sec'}})) { $entries{$fields{'sec'}} =~ s/\W//g; my $item = $entries{$fields{'sec'}}; if ($item eq "none" || $item eq 'all') { $r->print('
'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a reserved word.',''.$username.'',$fname,$mname,$lname,$gen,$item)); next; } elsif (exists($curr_groups{$item})) { $r->print('
'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]" - this is a course group.',''.$username.'',$fname,$mname,$lname,$gen,$item).' '.&mt('Section names and group names must be distinct.')); next; } else { push(@secs,$item); } } } if ($env{'request.course.sec'} ne '') { @secs = ($env{'request.course.sec'}); if (ref($userlist{$username.':'.$userdomain}) eq 'ARRAY') { my $currsec = $userlist{$username.':'.$userdomain}[$secidx]; if ($currsec ne $env{'request.course.sec'}) { $r->print('
'.&mt('[_1]: Unable to enroll user [_2] [_3] [_4] [_5] in a section named "[_6]".',''.$username.'',$fname,$mname,$lname,$gen,$secs[0]).'
'); if ($currsec eq '') { $r->print(&mt('This user already has an active/future student role in the course, unaffiliated to any section.')); } else { $r->print(&mt('This user already has an active/future role in section "[_1]" of the course.',$currsec)); } $r->print('
'.&mt('Although your current role has privileges to add students to section "[_1]", you do not have privileges to modify existing enrollments in other sections.',$secs[0]).'
'); next; } } } elsif ($context eq 'course' || $setting eq 'course') { if (@secs == 0) { @secs = @cleansec; } } # determine id number my $id=''; if (defined($fields{'id'})) { if (defined($entries{$fields{'id'}})) { $id=$entries{$fields{'id'}}; } $id=~tr/A-Z/a-z/; } # determine email address my $email=''; if (defined($fields{'email'})) { if (defined($entries{$fields{'email'}})) { $email=$entries{$fields{'email'}}; unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; } } } # determine user password my $password = $genpwd; if (defined($fields{'ipwd'})) { if ($entries{$fields{'ipwd'}}) { $password=$entries{$fields{'ipwd'}}; } } # determine user role my $role = ''; if (defined($fields{'role'})) { if ($entries{$fields{'role'}}) { $entries{$fields{'role'}} =~ s/(\s+$|^\s+)//g; if ($entries{$fields{'role'}} ne '') { if (grep(/^\Q$entries{$fields{'role'}}\E$/,@permitted_roles)) { $role = $entries{$fields{'role'}}; } } if ($role eq '') { my $rolestr = join(', ',@permitted_roles); $r->print('
' .&mt('[_1]: You do not have permission to add the requested role [_2] for the user.' ,''.$entries{$fields{'username'}}.'' ,$entries{$fields{'role'}}) .'
' .&mt('Allowable role(s) is/are: [_1].',$rolestr)."\n" ); next; } } } if ($role eq '') { $role = $defaultrole; } # Clean up whitespace foreach (\$id,\$fname,\$mname,\$lname,\$gen) { $$_ =~ s/(\s+$|^\s+)//g; } # check against rules my $checkid = 0; my $newuser = 0; my (%rulematch,%inst_results,%idinst_results); my $uhome=&Apache::lonnet::homeserver($username,$userdomain); if ($uhome eq 'no_host') { next if ($userdomain ne $domain); $checkid = 1; $newuser = 1; my $checkhash; my $checks = { 'username' => 1 }; $checkhash->{$username.':'.$domain} = { 'newuser' => 1, }; &Apache::loncommon::user_rule_check($checkhash,$checks, \%alerts,\%rulematch,\%inst_results,\%curr_rules, \%got_rules); if (ref($alerts{'username'}) eq 'HASH') { if (ref($alerts{'username'}{$domain}) eq 'HASH') { next if ($alerts{'username'}{$domain}{$username}); } } } else { if ($context eq 'course' || $context eq 'author') { if ($userdomain eq $domain ) { if ($role eq '') { my @checkroles; foreach my $role (@poss_roles) { my $endkey; if ($role ne 'st') { $endkey = ':'.$role; } if (exists($userlist{$username.':'.$userdomain.$endkey})) { if (!grep(/^\Q$role\E$/,@checkroles)) { push(@checkroles,$role); } } } if (@checkroles > 0) { %canmodify = &can_modify_userinfo($context,$domain,\@userinfo,\@checkroles); } } elsif (ref($modifiable_fields{$role}) eq 'HASH') { %canmodify = %{$modifiable_fields{$role}}; } } my @newinfo = (\$fname,\$mname,\$lname,\$gen,\$email,\$id); for (my $i=0; $i<@userinfo; $i++) { if (${$newinfo[$i]} ne '') { if (!$canmodify{$userinfo[$i]}) { ${$newinfo[$i]} = ''; } } } } } if ($id ne '') { if (!$newuser) { my %idhash = &Apache::lonnet::idrget($userdomain,($username)); if ($idhash{$username} ne $id) { $checkid = 1; } } if ($checkid) { my $checkhash; my $checks = { 'id' => 1 }; $checkhash->{$username.':'.$userdomain} = { 'newuser' => $newuser, 'id' => $id }; &Apache::loncommon::user_rule_check($checkhash,$checks, \%alerts,\%rulematch,\%idinst_results,\%curr_rules, \%got_rules); if (ref($alerts{'id'}) eq 'HASH') { if (ref($alerts{'id'}{$userdomain}) eq 'HASH') { next if ($alerts{'id'}{$userdomain}{$id}); } } } } if ($password || $env{'form.login'} eq 'loc') { my $multiple = 0; my ($userresult,$authresult,$roleresult,$idresult); my (%userres,%authres,%roleres,%idres); my $singlesec = ''; if ($role eq 'st') { my $sec; if (@secs > 0) { $sec = $secs[0]; } &modifystudent($userdomain,$username,$cid,$sec, $desiredhost,$context); $roleresult = &Apache::lonnet::modifystudent ($userdomain,$username,$id,$amode,$password, $fname,$mname,$lname,$gen,$sec,$enddate, $startdate,$env{'form.forceid'}, $desiredhost,$email,'manual','',$cid, '',$context); $userresult = $roleresult; } else { if ($role ne '') { if ($context eq 'course' || $setting eq 'course') { if ($customroles{$role}) { $role = 'cr_'.$env{'user.domain'}.'_'. $env{'user.name'}.'_'.$role; } if ($role ne 'cc') { if (@secs > 1) { $multiple = 1; foreach my $sec (@secs) { ($userres{$sec},$authres{$sec},$roleres{$sec},$idres{$sec}) = &modifyuserrole($context,$setting, $changeauth,$cid,$userdomain,$username, $id,$amode,$password,$fname, $mname,$lname,$gen,$sec, $env{'form.forceid'},$desiredhost, $email,$role,$enddate, $startdate,$checkid); } } elsif (@secs > 0) { $singlesec = $secs[0]; } } } } if (!$multiple) { ($userresult,$authresult,$roleresult,$idresult) = &modifyuserrole($context,$setting, $changeauth,$cid,$userdomain,$username, $id,$amode,$password,$fname, $mname,$lname,$gen,$singlesec, $env{'form.forceid'},$desiredhost, $email,$role,$enddate,$startdate,$checkid); } } if ($multiple) { foreach my $sec (sort(keys(%userres))) { $flushc = &user_change_result($r,$userres{$sec},$authres{$sec}, $roleres{$sec},$idres{$sec},\%counts,$flushc, $username,$userdomain,\%userchg); } } else { $flushc = &user_change_result($r,$userresult,$authresult, $roleresult,$idresult,\%counts,$flushc, $username,$userdomain,\%userchg); } } else { if ($context eq 'course') { $r->print('
'. &mt('[_1]: Unable to enroll. No password specified.',''.$username.'') ); } elsif ($context eq 'author') { $r->print('
'. &mt('[_1]: Unable to add co-author. No password specified.',''.$username.'') ); } else { $r->print('
'. &mt('[_1]: Unable to add user. No password specified.',''.$username.'') ); } } } } } # end of foreach (@userdata) # Flush the course logs so reverse user roles immediately updated &Apache::lonnet::flushcourselogs(); $r->print("

\n

\n".&mt('Processed [quant,_1,user].',$counts{'user'}). "

\n"); if ($counts{'role'} > 0) { $r->print("

\n". &mt('Roles added for [quant,_1,user].',$counts{'role'}).' '.&mt('If a user is currently logged-in to LON-CAPA, any new roles which are active will be available when the user next logs in.')."

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

'.&mt('No roles added').'

'); } if ($counts{'auth'} > 0) { $r->print("

\n". &mt('Authentication changed for [_1] existing users.', $counts{'auth'})."

\n"); } $r->print(&print_namespacing_alerts($domain,\%alerts,\%curr_rules)); ##################################### # Display list of students to drop # ##################################### if ($env{'form.fullup'} eq 'yes') { $r->print('

'.&mt('Students to Drop')."

\n"); # Get current classlist my $classlist = &Apache::loncoursedata::get_classlist(); if (! defined($classlist)) { $r->print(''. ''. &mt('There are no students with current/future access to the course.'). '
'."\n"); } elsif (ref($classlist) eq 'HASH') { # Remove the students we just added from the list of students. foreach my $line (@userdata) { my %entries=&Apache::loncommon::record_sep($line); unless (($entries{$fields{'username'}} eq '') || (!defined($entries{$fields{'username'}}))) { delete($classlist->{$entries{$fields{'username'}}. ':'.$domain}); } } # Print out list of dropped students. &show_drop_list($r,$classlist,'nosort',$permission); } } } # end of unless if ($env{'form.fullup'} ne 'yes') { $r->print(''); } } sub print_namespacing_alerts { my ($domain,$alerts,$curr_rules) = @_; my $output; if (ref($alerts) eq 'HASH') { if (keys(%{$alerts}) > 0) { if (ref($alerts->{'username'}) eq 'HASH') { foreach my $dom (sort(keys(%{$alerts->{'username'}}))) { my $count; if (ref($alerts->{'username'}{$dom}) eq 'HASH') { $count = keys(%{$alerts->{'username'}{$dom}}); } my $domdesc = &Apache::lonnet::domain($domain,'description'); if (ref($curr_rules->{$dom}) eq 'HASH') { $output .= &Apache::loncommon::instrule_disallow_msg( 'username',$domdesc,$count,'upload'); } $output .= &Apache::loncommon::user_rule_formats($dom, $domdesc,$curr_rules->{$dom}{'username'}, 'username'); } } if (ref($alerts->{'id'}) eq 'HASH') { foreach my $dom (sort(keys(%{$alerts->{'id'}}))) { my $count; if (ref($alerts->{'id'}{$dom}) eq 'HASH') { $count = keys(%{$alerts->{'id'}{$dom}}); } my $domdesc = &Apache::lonnet::domain($domain,'description'); if (ref($curr_rules->{$dom}) eq 'HASH') { $output .= &Apache::loncommon::instrule_disallow_msg( 'id',$domdesc,$count,'upload'); } $output .= &Apache::loncommon::user_rule_formats($dom, $domdesc,$curr_rules->{$dom}{'id'},'id'); } } } } } sub user_change_result { my ($r,$userresult,$authresult,$roleresult,$idresult,$counts,$flushc, $username,$userdomain,$userchg) = @_; my $okresult = 0; if ($userresult ne 'ok') { if ($userresult =~ /^error:(.+)$/) { my $error = $1; $r->print('
'. &mt('[_1]: Unable to add/modify: [_2]',''.$username.':'.$userdomain.'',$error)); } } else { $counts->{'user'} ++; $okresult = 1; } if ($authresult ne 'ok') { if ($authresult =~ /^error:(.+)$/) { my $error = $1; $r->print('
'. &mt('[_1]: Unable to modify authentication: [_2]',''.$username.':'.$userdomain.'',$error)); } } else { $counts->{'auth'} ++; $okresult = 1; } if ($roleresult ne 'ok') { if ($roleresult =~ /^error:(.+)$/) { my $error = $1; $r->print('
'. &mt('[_1]: Unable to add role: [_2]',''.$username.':'.$userdomain.'',$error)); } } else { $counts->{'role'} ++; $okresult = 1; } if ($okresult) { $flushc++; $userchg->{$username.':'.$userdomain}=1; $r->print('. '); if ($flushc>15) { $r->rflush; $flushc=0; } } if ($idresult) { $r->print($idresult); } return $flushc; } # ========================================================= Menu Phase Two Drop sub print_drop_menu { my ($r,$context,$permission) = @_; $r->print('

'.&mt("Drop Students").'

'."\n". '
'."\n"); my $classlist = &Apache::loncoursedata::get_classlist(); if (! defined($classlist)) { $r->print(&mt('There are no students currently enrolled.')."\n"); } else { &show_drop_list($r,$classlist,'nosort',$permission); } $r->print('
'. &Apache::loncommon::end_page()); return; } # ================================================================== Phase four sub update_user_list { my ($r,$context,$setting,$choice) = @_; my $now = time; my $count=0; my @changelist; if ($choice eq 'drop') { @changelist = &Apache::loncommon::get_env_multiple('form.droplist'); } else { @changelist = &Apache::loncommon::get_env_multiple('form.actionlist'); } my %result_text = ( ok => { 'revoke' => 'Revoked', 'delete' => 'Deleted', 'reenable' => 'Re-enabled', 'activate' => 'Activated', 'chgdates' => 'Changed Access Dates for', 'chgsec' => 'Changed section for', 'drop' => 'Dropped', }, error => {'revoke' => 'revoking', 'delete' => 'deleting', 'reenable' => 're-enabling', 'activate' => 'activating', 'chgdates' => 'changing access dates for', 'chgsec' => 'changing section for', 'drop' => 'dropping', }, ); my ($startdate,$enddate); if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') { ($startdate,$enddate) = &get_dates_from_form(); } foreach my $item (@changelist) { my ($role,$uname,$udom,$cid,$sec,$scope,$result,$type,$locktype,@sections, $scopestem); if ($choice eq 'drop') { ($uname,$udom,$sec) = split(/:/,$item,-1); $role = 'st'; $cid = $env{'request.course.id'}; $scopestem = '/'.$cid; $scopestem =~s/\_/\//g; if ($sec eq '') { $scope = $scopestem; } else { $scope = $scopestem.'/'.$sec; } } elsif ($context eq 'course') { ($uname,$udom,$role,$sec,$type,$locktype) = split(/\:/,$item,-1); $cid = $env{'request.course.id'}; $scopestem = '/'.$cid; $scopestem =~s/\_/\//g; if ($sec eq '') { $scope = $scopestem; } else { $scope = $scopestem.'/'.$sec; } } elsif ($context eq 'author') { ($uname,$udom,$role) = split(/\:/,$item,-1); $scope = '/'.$env{'user.domain'}.'/'.$env{'user.name'}; } elsif ($context eq 'domain') { if ($setting eq 'domain') { ($role,$uname,$udom) = split(/\:/,$item,-1); $scope = '/'.$env{'request.role.domain'}.'/'; } elsif ($setting eq 'author') { ($uname,$udom,$role,$scope) = split(/\:/,$item); } elsif ($setting eq 'course') { ($uname,$udom,$role,$cid,$sec,$type,$locktype) = split(/\:/,$item); $scope = '/'.$cid; $scope =~s/\_/\//g; if ($sec ne '') { $scope .= '/'.$sec; } } } my $plrole = &Apache::lonnet::plaintext($role); my $start = $env{'form.'.$item.'_start'}; my $end = $env{'form.'.$item.'_end'}; if ($choice eq 'drop') { # drop students $end = $now; $type = 'manual'; $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } elsif ($choice eq 'revoke') { # revoke or delete user role $end = $now; if ($role eq 'st') { $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } else { $result = &Apache::lonnet::revokerole($udom,$uname,$scope,$role, '','',$context); } } elsif ($choice eq 'delete') { if ($role eq 'st') { &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$now,$start,$type,$locktype,$cid,'',$context); } $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$now, $start,1,'',$context); } else { #reenable, activate, change access dates or change section if ($choice ne 'chgsec') { $start = $startdate; $end = $enddate; } if ($choice eq 'reenable') { if ($role eq 'st') { $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } else { $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end, $now,'','',$context); } } elsif ($choice eq 'activate') { if ($role eq 'st') { $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } else { $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end, $now,'','',$context); } } elsif ($choice eq 'chgdates') { if ($role eq 'st') { $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$sec,$end,$start,$type,$locktype,$cid,'',$context); } else { $result = &Apache::lonnet::assignrole($udom,$uname,$scope,$role,$end, $start,'','',$context); } } elsif ($choice eq 'chgsec') { my (@newsecs,$revresult,$nochg,@retained); if ($role ne 'cc') { @newsecs = split(/,/,$env{'form.newsecs'}); } # remove existing section if not to be retained. if (!$env{'form.retainsec'}) { if ($sec eq '') { if (@newsecs == 0) { $result = &mt('No change in section assignment (none)'); $nochg = 1; } else { $revresult = &Apache::lonnet::revokerole($udom,$uname, $scope,$role, '','',$context); } } else { if (@newsecs > 0) { if (grep(/^\Q$sec\E$/,@newsecs)) { push(@retained,$sec); } else { $revresult = &Apache::lonnet::revokerole($udom,$uname, $scope,$role, '','',$context); } } else { $revresult = &Apache::lonnet::revokerole($udom,$uname, $scope,$role, '','',$context); } } } else { if ($sec eq '') { $nochg = 1; } else { push(@retained,$sec); } } # add new sections if (@newsecs == 0) { if (!$nochg) { if ($role eq 'st') { $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,undef,$end,$start,$type,$locktype,$cid,'',$context); } else { my $newscope = $scopestem; $result = &Apache::lonnet::assignrole($udom,$uname,$newscope,$role,$end,$start,'','',$context); } } } else { foreach my $newsec (@newsecs) { if (!grep(/^\Q$newsec\E$/,@retained)) { if ($role eq 'st') { $result = &Apache::lonnet::modify_student_enrollment($udom,$uname,undef,undef,undef,undef,undef,$newsec,$end,$start,$type,$locktype,$cid,'',$context); } else { my $newscope = $scopestem; if ($newsec ne '') { $newscope .= '/'.$newsec; } $result = &Apache::lonnet::assignrole($udom,$uname, $newscope,$role,$end,$start); } } } } } } my $extent = $scope; if ($choice eq 'drop' || $context eq 'course') { my ($cnum,$cdom,$cdesc) = &get_course_identity($cid); if ($cdesc) { $extent = $cdesc; } } if ($result eq 'ok' || $result eq 'ok:') { $r->print(&mt("$result_text{'ok'}{$choice} role of '[_1]' in [_2] for [_3]", $plrole,$extent,$uname.':'.$udom).'
'); $count++; } else { $r->print( &mt("Error $result_text{'error'}{$choice} [_1] in [_2] for [_3]: [_4].", $plrole,$extent,$uname.':'.$udom,$result).'
'); } } $r->print('
'."\n"); if ($choice eq 'drop') { $r->print(''."\n". ''."\n". ''."\n"); } else { foreach my $item ('action','sortby','roletype','showrole','Status','secfilter','grpfilter') { if ($env{'form.'.$item} ne '') { $r->print(''."\n"); } } } $r->print('

'.&mt("$result_text{'ok'}{$choice} role(s) for [quant,_1,user,users,no users].",$count).'

'); if ($count > 0) { if ($choice eq 'revoke' || $choice eq 'drop') { $r->print('

'.&mt('Re-enabling will re-activate data for the role.').'

'); } # Flush the course logs so reverse user roles immediately updated &Apache::lonnet::flushcourselogs(); } if ($env{'form.makedatesdefault'}) { if ($choice eq 'chgdates' || $choice eq 'reenable' || $choice eq 'activate') { $r->print(&make_dates_default($startdate,$enddate,$context)); } } my $linktext = &mt('Display User Lists'); if ($choice eq 'drop') { $linktext = &mt('Display current class roster'); } $r->print(''.$linktext.'
'."\n"); } sub classlist_drop { my ($scope,$uname,$udom,$now) = @_; my ($cdom,$cnum) = ($scope=~m{^/($match_domain)/($match_courseid)}); if (&Apache::lonnet::is_course($cdom,$cnum)) { if (!&active_student_roles($cnum,$cdom,$uname,$udom)) { my %user; my $result = &update_classlist($cdom,$cnum,$udom,$uname,\%user,$now); return &mt('Drop from classlist: [_1]', ''.$result.'').'
'; } } } sub active_student_roles { my ($cnum,$cdom,$uname,$udom) = @_; my %roles = &Apache::lonnet::get_my_roles($uname,$udom,'userroles', ['future','active'],['st']); return exists($roles{"$cnum:$cdom:st"}); } sub section_check_js { my $groupslist= &get_groupslist(); return <<"END"; function validate(caller) { var groups = new Array($groupslist); var secname = caller.value; if ((secname == 'all') || (secname == 'none')) { alert("'"+secname+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name."); return 'error'; } if (secname != '') { for (var k=0; k'.$authformkrb.''. &Apache::loncommon::end_data_table_row()."\n"; } if ($can_assign{'int'}) { $response .= &Apache::loncommon::start_data_table_row(). ''.$authformint.''. &Apache::loncommon::end_data_table_row()."\n" } if ($can_assign{'loc'}) { $response .= &Apache::loncommon::start_data_table_row(). ''.$authformloc.''. &Apache::loncommon::end_data_table_row()."\n"; } $response .= &Apache::loncommon::end_data_table(); } return $response; } sub course_sections { my ($sections_count,$role,$current_sec) = @_; my $output = ''; my @sections = (sort {$a <=> $b} keys %{$sections_count}); my $numsec = scalar(@sections); my $is_selected = ' selected="selected" '; if ($numsec <= 1) { $output = ''.&mt('Select').''."\n"; if ($current_sec eq 'none') { $output .= ' \n"; } else { $output .= ' \n"; } } else { $output .= 'multiple="multiple" size="'.$multiple.'">'."\n"; } foreach my $sec (@sections) { if ($current_sec eq $sec) { $output .= '\n"; } else { $output .= '\n"; } } } $output .= ''; return $output; } sub get_groupslist { my $groupslist; my %curr_groups = &Apache::longroup::coursegroups(); if (%curr_groups) { $groupslist = join('","',sort(keys(%curr_groups))); $groupslist = '"'.$groupslist.'"'; } return $groupslist; } sub setsections_javascript { my ($formname,$groupslist,$mode,$checkauth) = @_; my ($checkincluded,$finish,$rolecode,$setsection_js); if ($mode eq 'upload') { $checkincluded = 'formname.name == "'.$formname.'"'; $finish = "return 'ok';"; $rolecode = "var role = formname.defaultrole.options[formname.defaultrole.selectedIndex].value;\n"; } elsif ($formname eq 'cu') { $checkincluded = 'formname.elements[i-1].checked == true'; if ($checkauth) { $finish = "var authcheck = auth_check();\n". " if (authcheck == 'ok') {\n". " formname.submit();\n". " }\n"; } else { $finish = 'formname.submit()'; } $rolecode = "var match = str.split('_'); var role = match[3];\n"; } elsif ($formname eq 'enrollstudent') { $checkincluded = 'formname.name == "'.$formname.'"'; if ($checkauth) { $finish = "var authcheck = auth_check();\n". " if (authcheck == 'ok') {\n". " formname.submit();\n". " }\n"; } else { $finish = 'formname.submit()'; } $rolecode = "var match = str.split('_'); var role = match[1];\n"; } else { $checkincluded = 'formname.name == "'.$formname.'"'; $finish = "seccheck = 'ok';"; $rolecode = "var match = str.split('_'); var role = match[1];\n"; $setsection_js = "var seccheck = 'alert';"; } my %alerts = &Apache::lonlocal::texthash( secd => 'Section designations do not apply to Course Coordinator roles.', accr => 'A course coordinator role will be added with access to all sections.', inea => 'In each course, each user may only have one student role at a time.', youh => 'You had selected ', secs => 'sections.', plmo => 'Please modify your selections so they include no more than one section.', mayn => 'may not be used as the name for a section, as it is a reserved word.', plch => 'Please choose a different section name.', mnot => 'may not be used as a section name, as it is the name of a course group.', secn => 'Section names and group names must be distinct. Please choose a different section name.', ); $setsection_js .= <<"ENDSECCODE"; function setSections(formname) { var re1 = /^currsec_/; var groups = new Array($groupslist); for (var i=0;i 0) { if (formname.elements[i+1].value != "" && formname.elements[i+1].value != null) { sections = sections + "," + formname.elements[i+1].value; } } else { sections = formname.elements[i+1].value; } var newsecs = formname.elements[i+1].value; var numsplit; if (newsecs != null && newsecs != "") { numsplit = newsecs.split(/,/g); numsec = numsec + numsplit.length; } if ((role == 'st') && (numsec > 1)) { alert("$alerts{'inea'} $alerts{'youh'} "+numsec+" $alerts{'secs'}\\n$alerts{'plmo'}") return; } else { if (numsplit != null) { for (var j=0; j 0) { my %rule_check = &Apache::lonnet::inst_rulecheck($dom,$uname,undef,'username',\@user_rules); if (keys(%rule_check) > 0) { $usertype = 'unofficial'; foreach my $item (keys(%rule_check)) { if ($rule_check{$item}) { $usertype = 'official'; last; } } } } } return $usertype; } sub roles_by_context { my ($context,$custom) = @_; my @allroles; if ($context eq 'course') { @allroles = ('st','ad','ta','ep','in','cc'); if ($custom) { push(@allroles,'cr'); } } elsif ($context eq 'author') { @allroles = ('ca','aa'); } elsif ($context eq 'domain') { @allroles = ('li','dg','sc','au','dc'); } return @allroles; } sub get_permission { my ($context,$roles) = @_; my %permission; if ($context eq 'course') { my $custom = 1; my @allroles = &roles_by_context($context,$custom); foreach my $role (@allroles) { if (&Apache::lonnet::allowed('c'.$role,$env{'request.course.id'})) { $permission{'cusr'} = 1; last; } } if (&Apache::lonnet::allowed('ccr',$env{'request.course.id'})) { $permission{'custom'} = 1; } if (&Apache::lonnet::allowed('vcl',$env{'request.course.id'})) { $permission{'view'} = 1; } if (!$permission{'view'}) { my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'}; $permission{'view'} = &Apache::lonnet::allowed('vcl',$scope); if ($permission{'view'}) { $permission{'view_section'} = $env{'request.course.sec'}; } } if (!$permission{'cusr'}) { if ($env{'request.course.sec'} ne '') { my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'}; $permission{'cusr'} = (&Apache::lonnet::allowed('cst',$scope)); if ($permission{'cusr'}) { $permission{'cusr_section'} = $env{'request.course.sec'}; } } } if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) { $permission{'grp_manage'} = 1; } } elsif ($context eq 'author') { $permission{'cusr'} = &authorpriv($env{'user.name'},$env{'request.role.domain'}); $permission{'view'} = $permission{'cusr'}; } else { my @allroles = &roles_by_context($context); foreach my $role (@allroles) { if (&Apache::lonnet::allowed('c'.$role,$env{'request.role.domain'})) { $permission{'cusr'} = 1; last; } } if (!$permission{'cusr'}) { if (&Apache::lonnet::allowed('mau',$env{'request.role.domain'})) { $permission{'cusr'} = 1; } } if (&Apache::lonnet::allowed('ccr',$env{'request.role.domain'})) { $permission{'custom'} = 1; } $permission{'view'} = $permission{'cusr'}; } my $allowed = 0; foreach my $perm (values(%permission)) { if ($perm) { $allowed=1; last; } } return (\%permission,$allowed); } # ==================================================== Figure out author access sub authorpriv { my ($auname,$audom)=@_; unless ((&Apache::lonnet::allowed('cca',$audom.'/'.$auname)) || (&Apache::lonnet::allowed('caa',$audom.'/'.$auname))) { return ''; } return 1; } sub roles_on_upload { my ($context,$setting,%customroles) = @_; my (@possible_roles,@permitted_roles); @possible_roles = &curr_role_permissions($context,$setting,1); foreach my $role (@possible_roles) { if ($role eq 'cr') { push(@permitted_roles,keys(%customroles)); } else { push(@permitted_roles,$role); } } return @permitted_roles; } sub get_course_identity { my ($cid) = @_; my ($cnum,$cdom,$cdesc); if ($cid eq '') { $cid = $env{'request.course.id'} } if ($cid ne '') { $cnum = $env{'course.'.$cid.'.num'}; $cdom = $env{'course.'.$cid.'.domain'}; $cdesc = $env{'course.'.$cid.'.description'}; if ($cnum eq '' || $cdom eq '') { my %coursehash = &Apache::lonnet::coursedescription($cid,{'one_time' => 1}); $cdom = $coursehash{'domain'}; $cnum = $coursehash{'num'}; $cdesc = $coursehash{'description'}; } } return ($cnum,$cdom,$cdesc); } sub dc_setcourse_js { my ($formname,$mode,$context) = @_; my ($dc_setcourse_code,$authen_check); my $cctext = &Apache::lonnet::plaintext('cc'); my %alerts = §ioncheck_alerts(); my $role = 'role'; if ($mode eq 'upload') { $role = 'courserole'; } else { $authen_check = &verify_authen($formname,$context); } $dc_setcourse_code = (<<"SCRIPTTOP"); $authen_check function setCourse() { var course = document.$formname.dccourse.value; if (course != "") { if (document.$formname.dcdomain.value != document.$formname.origdom.value) { alert("$alerts{'curd'}"); return; } var userrole = document.$formname.$role.options[document.$formname.$role.selectedIndex].value var section=""; var numsections = 0; var newsecs = new Array(); for (var i=0; i 1)) { alert("$alerts{'inea'}. $alerts{'youh'} "+numsections+" $alerts{'sect'}.\\n$alerts{'plsm'}.") return; } for (var j=0; j 0)) { alert("$alerts{'secd'} $cctext $alerts{'role'}.\\n$alerts{'accr'}."); section = ""; } SCRIPTTOP if ($mode ne 'upload') { $dc_setcourse_code .= (<<"ENDSCRIPT"); var coursename = "_$env{'request.role.domain'}"+"_"+course+"_"+userrole var numcourse = getIndex(document.$formname.dccourse); if (numcourse == "-1") { alert("$alerts{'thwa'}"); return; } else { document.$formname.elements[numcourse].name = "act"+coursename; var numnewsec = getIndex(document.$formname.newsec); if (numnewsec != "-1") { document.$formname.elements[numnewsec].name = "sec"+coursename; document.$formname.elements[numnewsec].value = section; } var numstart = getIndex(document.$formname.start); if (numstart != "-1") { document.$formname.elements[numstart].name = "start"+coursename; } var numend = getIndex(document.$formname.end); if (numend != "-1") { document.$formname.elements[numend].name = "end"+coursename } } } var authcheck = auth_check(); if (authcheck == 'ok') { document.$formname.submit(); } } ENDSCRIPT } else { $dc_setcourse_code .= " document.$formname.sections.value = section; } return 'ok'; } "; } $dc_setcourse_code .= (<<"ENDSCRIPT"); function getIndex(caller) { for (var i=0;i 0) { var loginpicked = 0; for (var i=0; i 'You must select a course in the current domain', inea => 'In each course, each user may only have one student role at a time', youh => 'You had selected', sect => 'sections', plsm => 'Please modify your selections so they include no more than one section', mayn => 'may not be used as the name for a section, as it is a reserved word', plsc => 'Please choose a different section name', mayt => 'may not be used as the name for a section, as it is the name of a course group', secn => 'Section names and group names must be distinct', secd => 'Section designations do not apply to ', role => 'roles', accr => 'role will be added with access to all sections', thwa => 'There was a problem with your course selection' ); return %alerts; } sub authcheck_alerts { my %alerts = &Apache::lonlocal::texthash( authen => 'You must choose an authentication type.', krb => 'You need to specify the Kerberos domain.', ipass => 'You need to specify the initial password.', ); return %alerts; } 1; 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.