--- loncom/interface/Attic/londropadd.pm 2003/12/28 01:30:50 1.97 +++ loncom/interface/Attic/londropadd.pm 2007/08/31 03:22:51 1.169 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to drop and add students in courses # -# $Id: londropadd.pm,v 1.97 2003/12/28 01:30:50 raeburn Exp $ +# $Id: londropadd.pm,v 1.169 2007/08/31 03:22:51 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -32,24 +32,28 @@ package Apache::londropadd; use strict; -use Apache::lonnet(); +use Apache::lonnet; use Apache::loncommon(); use Apache::lonhtmlcommon(); use Apache::Constants qw(:common :http REDIRECT); use Spreadsheet::WriteExcel; +use Apache::lonstathelpers(); use Apache::lonlocal; +use Apache::longroup; +use LONCAPA(); ############################################################### ############################################################### sub header { - my $bodytag=&Apache::loncommon::bodytag('Enrollment Manager'); - my $title = &mt('LON-CAPA Enrollment Manager'); + my ($jscript,$loaditems) = @_; + my $start_page; + if (ref($loaditems) eq 'HASH') { + $start_page=&Apache::loncommon::start_page('Enrollment Manager',$jscript,{'add_entries' => $loaditems,}); + } else { + $start_page=&Apache::loncommon::start_page('Enrollment Manager',$jscript); + } return(<<ENDHEAD); -<html> -<head> -<title>$title</title> -</head> -$bodytag +$start_page <form method="post" enctype="multipart/form-data" action="/adm/dropadd" name="studentform"> ENDHEAD @@ -63,8 +67,8 @@ sub modifystudent { # 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 - $courseid=~s/\_/\//g; - $courseid=~s/^(\w)/\/$1/; + my $cdom = $env{'course.'.$courseid.'.domain'}; + my $cnum = $env{'course.'.$courseid.'.num'}; my %roles = &Apache::lonnet::dump('roles',$udom,$unam); my ($tmp) = keys(%roles); # Bail out if we were unable to get the students roles @@ -72,16 +76,16 @@ sub modifystudent { # Go through the roles looking for enrollment in this course my $result = ''; foreach my $course (keys(%roles)) { - if ($course=~/^$courseid(?:\/)*(?:\s+)*(\w+)*\_st$/) { + if ($course=~m{^/\Q$cdom\E/\Q$cnum\E(?:\/)*(?:\s+)*(\w+)*\_st$}) { # We are in this course my $section=$1; - $section='' if ($course eq $courseid.'_st'); + $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 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 @@ -108,7 +112,7 @@ sub domain_form { # Set up domain and server selection forms # # Get the domains - my @domains = &Apache::loncommon::get_domains(); + my @domains = &Apache::lonnet::all_domains(); # build up the menu information to be passed to # &Apache::loncommon::linked_select_forms my %select_menus; @@ -119,7 +123,7 @@ sub domain_form { $select_menus{$dom}->{'default'}= 'default'; $select_menus{$dom}->{'select2'}->{'default'} = 'default'; # Now build up the other items in the second menu - my %servers = &Apache::loncommon::get_library_servers($dom); + my %servers = &Apache::lonnet::get_servers($dom,'library'); foreach my $server (keys(%servers)) { $select_menus{$dom}->{'select2'}->{$server} = "$server $servers{$server}"; @@ -135,41 +139,89 @@ sub domain_form { ############################################################### # Menu Phase One sub print_main_menu { - my $r=shift; - my %Text = &Apache::lonlocal::texthash - ('upload' => 'Upload a class list', - 'enrollone' => 'Enroll a single student', - 'modify' => 'Modify student data', - 'view' => 'View Class List', - 'drop' => 'Drop Students', - 'populate' => 'Automated Enrollment Manager'); - - $r->print(<<END); -<p> -<font size="+1"> - <a href="/adm/dropadd?action=upload">$Text{'upload'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/dropadd?action=enrollstudent">$Text{'enrollone'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/dropadd?action=modifystudent">$Text{'modify'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/dropadd?action=classlist">$Text{'view'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/dropadd?action=drop">$Text{'drop'}</a> -</font> -</p><p> -<font size="+1"> - <a href="/adm/populate">$Text{'populate'}</a> -</font> -END + my ($r,$permission)=@_; + # + my $cid =$env{'request.course.id'}; + my $cdom=$env{'course.'.$cid.'.domain'}; + my $cnum=$env{'course.'.$cid.'.num'}; + my @menu = + ( + { text => 'Upload a class list', + help => 'Course_Create_Class_List', + action => 'upload', + permission => $permission->{'enrl'}, + }, + { text => 'Enroll a single student', + help => 'Course_Add_Student', + action => 'enrollstudent', + permission => $permission->{'enrl'}, + }, + { text => 'Modify student data', + help => 'Course_Modify_Student_Data', + action => 'modifystudent', + permission => $permission->{'enrl'}, + }, + { text => 'View Class List', + help => 'Course_View_Class_List', + action => 'classlist', + permission => $permission->{'view'}, + }, + { text => 'Drop Students', + help => 'Course_Drop_Student', + action => 'drop', + permission => $permission->{'enrl'}, + }, + { text => 'Automated Enrollment Manager', + permission => (&Apache::lonnet::auto_run($cnum,$cdom) + && $permission->{'enrl'}), + url => '/adm/populate', + }, + { text => 'Create a new group', + help => 'Course_Create_Group', + permission => $permission->{'grp_manage'}, + url => '/adm/coursegroups?refpage=enrl&action=create', + }, + { text => 'Modify an existing group', + help => 'Course_Modify_Group', + permission => $permission->{'grp_manage'}, + url => '/adm/coursegroups?refpage=enrl&action=modify', + }, + { text => 'Delete an existing group', + help => 'Course_Delete_Group', + permission => $permission->{'grp_manage'}, + url => '/adm/coursegroups?refpage=enrl&action=delete', + }, + { text => 'Re-enable a deleted group', + help => 'Course_Reenable_Group', + permission => $permission->{'grp_manage'}, + url => '/adm/coursegroups?refpage=enrl&action=reenable', + }, + { text => 'Enter an existing group', + help => 'Course_Display_Group', + permission => $permission->{'grp_view'}, + url => '/adm/coursegroups?refpage=enrl&action=view', + }, + ); + my $menu_html = ''; + foreach my $menu_item (@menu) { + next if (! $menu_item->{'permission'}); + $menu_html.='<p>'; + $menu_html.='<font size="+1">'; + if (exists($menu_item->{'url'})) { + $menu_html.=qq{<a href="$menu_item->{'url'}">}; + } else { + $menu_html.= + qq{<a href="/adm/dropadd?action=$menu_item->{'action'}">}; + } + $menu_html.= &mt($menu_item->{'text'}).'</a></font>'; + if (exists($menu_item->{'help'})) { + $menu_html.= + &Apache::loncommon::help_open_topic($menu_item->{'help'}); + } + $menu_html.='</p>'.$/; + } + $r->print($menu_html); + return; } ############################################################### @@ -182,23 +234,37 @@ sub hidden_input { sub print_upload_manager_header { my ($r,$datatoken,$distotal,$krbdefdom)=@_; my $javascript; - if (! exists($ENV{'form.upfile_associate'})) { - $ENV{'form.upfile_associate'} = 'forward'; + # + 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'; + 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'; + $env{'form.upfile_associate'} = 'forward'; } } - if ($ENV{'form.upfile_associate'} eq 'reverse') { + if ($env{'form.upfile_associate'} eq 'reverse') { $javascript=&upload_manager_javascript_reverse_associate(); } else { $javascript=&upload_manager_javascript_forward_associate(); } - my $javascript_validations=&javascript_validations('auth',$krbdefdom); - my $checked=(($ENV{'form.noFirstLine'})?' checked="1"':''); + # + # 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 $javascript_validations=&javascript_validations('auth',$krbdefdom, + $password_choice); + my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':''); $r->print('<h3>'.&mt('Uploading Class List')."</h3>\n". "<hr>\n". '<h3>'.&mt('Identify fields')."</h3>\n"); @@ -211,14 +277,14 @@ sub print_upload_manager_header { &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'})); + &hidden_input('fileupload',$env{'form.fileupload'}). + &hidden_input('upfiletype',$env{'form.upfiletype'}). + &hidden_input('upfile_associate',$env{'form.upfile_associate'})); $r->print('<input type="button" value="Reverse Association" '. 'name="'.&mt('Reverse Association').'" '. 'onClick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />'); - $r->print('<input type="checkbox" name="noFirstLine" $checked />'. - &mt('Ignore First Line')); + $r->print('<label><input type="checkbox" name="noFirstLine"'.$checked.'/>'. + &mt('Ignore First Line').'</label>'); $r->print("<hr />\n". '<script type="text/javascript" language="Javascript">'."\n". $javascript."\n".$javascript_validations.'</script>'); @@ -231,11 +297,13 @@ sub javascript_validations { my $authheader; if ($mode eq 'auth') { my %param = ( formname => 'studentform', - kerb_def_dom => $krbdefdom ); + kerb_def_dom => $krbdefdom, + curr_authtype => $curr_authtype); $authheader = &Apache::loncommon::authform_header(%param); } elsif ($mode eq 'createcourse') { my %param = ( formname => 'ccrs', - kerb_def_dom => $krbdefdom ); + kerb_def_dom => $krbdefdom, + curr_authtype => $curr_authtype ); $authheader = &Apache::loncommon::authform_header(%param); } elsif ($mode eq 'modifycourse') { my %param = ( formname => 'cmod', @@ -254,7 +322,7 @@ sub javascript_validations { ipass => 'You need to specify the initial password.', name => 'The optional name field was not specified.', snum => 'The optional student number field was not specified.', - section => 'The optional section or group field was not specified.', + section => 'The optional section field was not specified.', email => 'The optional email address field was not specified.', continue => 'Continue enrollment?', ); @@ -281,7 +349,7 @@ END return; } // alert('current.radiovalue = '+current.radiovalue); - if (current.radiovalue == null || current.radiovalue == 'nochange') { + if (current.radiovalue == null || current.radiovalue == '' || current.radiovalue == 'nochange') { // They did not check any of the login radiobuttons. alert('$alert{'authen'}'); return; @@ -340,6 +408,7 @@ END } END } + my $section_checks; my $optional_checks = ''; if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) { $optional_checks = (<<END); @@ -347,6 +416,7 @@ END } END } else { + $section_checks = §ion_check_js(); $optional_checks = (<<END); var message=''; if (foundname==0) { @@ -387,7 +457,7 @@ END if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) { $result .= $auth_checks; } - $result .= $optional_checks; + $result .= $optional_checks."\n".$section_checks; if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) { $result .= $authheader; } @@ -398,7 +468,7 @@ END ############################################################### sub upload_manager_javascript_forward_associate { return(<<ENDPICK); -function verify(vf) { +function verify(vf,sec_caller) { var founduname=0; var foundpwd=0; var foundname=0; @@ -491,7 +561,7 @@ ENDPICK ############################################################### sub upload_manager_javascript_reverse_associate { return(<<ENDPICK); -function verify(vf) { +function verify(vf,sec_caller) { var founduname=0; var foundpwd=0; var foundname=0; @@ -553,6 +623,11 @@ sub print_upload_manager_footer { 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); @@ -564,6 +639,7 @@ sub print_upload_manager_footer { $Str .= '<h3>'.&mt('Login Type')."</h3>\n"; $Str .= "<p>\n". &mt('Note: this will not take effect if the user already exists'). + &Apache::loncommon::help_open_topic('Auth_Options'). "</p><p>\n"; $Str .= $krbform."\n</p><p>\n". $intform."\n</p><p>\n". @@ -573,15 +649,16 @@ sub print_upload_manager_footer { $Str .= "<h3>".&mt('Starting and Ending Dates')."</h3>\n"; $Str .= "<p>\n".$date_table."</p>\n"; $Str .= "<h3>".&mt('Full Update')."</h3>\n"; - $Str .= '<input type="checkbox" name="fullup" value="yes">'. + $Str .= '<label><input type="checkbox" name="fullup" value="yes">'. ' '.&mt('Full update (also print list of users not enrolled anymore)'). - "</p>\n"; + "</label></p>\n"; $Str .= "<h3>".&mt('Student Number')."</h3>\n"; - $Str .= "<p>\n".'<input type="checkbox" name="forceid" value="yes">'; + $Str .= "<p>\n".'<label><input type="checkbox" name="forceid" value="yes">'; $Str .= &mt('Disable ID/Student Number Safeguard and Force Change '. 'of Conflicting IDs (only do if you know what you are doing)'). - "\n</p><p>\n"; - $Str .= '<input type="button" onClick="javascript:verify(this.form)" '. + "</label>\n</p><p>\n"; + $Str .= '<input type="button"'. + 'onClick="javascript:verify(this.form,this.form.csec)" '. 'value="Update Class List" />'."<br />\n"; $Str .= &mt('Note: for large courses, this operation may be time '. 'consuming'); @@ -593,40 +670,59 @@ sub print_upload_manager_footer { ############################################################### sub print_upload_manager_form { my $r=shift; + my $firstLine; my $datatoken; - if (!$ENV{'form.datatoken'}) { + if (!$env{'form.datatoken'}) { $datatoken=&Apache::loncommon::upfile_store($r); } else { - $datatoken=$ENV{'form.datatoken'}; + $datatoken=$env{'form.datatoken'}; &Apache::loncommon::load_tmp_file($r); } my @records=&Apache::loncommon::upfile_record_sep(); - if($ENV{'form.noFirstLine'}){ + if($env{'form.noFirstLine'}){ $firstLine=shift(@records); } my $total=$#records; my $distotal=$total+1; my $today=time; my $halfyear=$today+15552000; - my $defdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; + # + # Restore memorized settings + &Apache::loncommon::restore_course_settings + ('enrollment_upload',{ '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', + }); + # + # Determine kerberos parameters as appropriate + my $defdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; my ($krbdef,$krbdefdom) = &Apache::loncommon::get_kerberos_defaults($defdom); + # &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom); my $i; my $keyfields; if ($total>=0) { - my @field=(['username',&mt('Username')], - ['names',&mt('Last Name, First Names')], - ['fname',&mt('First Name')], - ['mname',&mt('Middle Names/Initials')], - ['lname',&mt('Last Name')], - ['gen',&mt('Generation')], - ['id',&mt('ID/Student Number')], - ['sec',&mt('Group/Section')], - ['ipwd',&mt('Initial Password')], - ['email',&mt('EMail Address')]); - if ($ENV{'form.upfile_associate'} eq 'reverse') { + 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('ID/Student Number'),$env{'form.id_choice'}], + ['sec', &mt('Section'), $env{'form.sec_choice'}], + ['ipwd', &mt('Initial Password'),$env{'form.ipwd_choice'}], + ['email',&mt('EMail Address'), $env{'form.email_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); @@ -648,31 +744,35 @@ sub print_upload_manager_form { ############################################################### ############################################################### sub enroll_single_student { - my $r=shift; + my ($r,$srcharray) = @_; # Remove non alphanumeric values from section - $ENV{'form.csec'}=~s/\W//g; + $env{'form.csec'}=~s/\W//g; # # We do the dates first because the action of making them the defaul - # in the course is entirely seperate from the action of enrolling the + # in the course is entirely separate from the action of enrolling the # student. Also, a failure in setting the dates as default is not fatal # to the process of enrolling / modifying a student. my ($startdate,$enddate) = &get_dates_from_form(); - if ($ENV{'form.makedatesdefault'}) { + if ($env{'form.makedatesdefault'}) { $r->print(&make_dates_default($startdate,$enddate)); } $r->print('<h3>'.&mt('Enrolling Student').'</h3>'); - $r->print('<p>'.&mt('Enrolling').' '.$ENV{'form.cuname'}." \@ ". - $ENV{'form.lcdomain'}.'</p>'); - if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&& - ($ENV{'form.lcdomain'})&&($ENV{'form.lcdomain'}!~/\W/)) { + $r->print('<p>'.&mt('Enrolling [_1] : [_2]',$env{'form.cuname'}, + $env{'form.lcdomain'}).'</p>'); + if (($env{'form.cuname'}) + && ($env{'form.cuname'} + eq &LONCAPA::clean_username($env{'form.cuname'})) + && ($env{'form.lcdomain'}) + && ($env{'form.lcdomain'} + eq &LONCAPA::clean_domain($env{'form.lcdomain'}))) { # Deal with home server selection - my $domain=$ENV{'form.lcdomain'}; - my $desiredhost = $ENV{'form.lcserver'}; + my $domain=$env{'form.lcdomain'}; + my $desiredhost = $env{'form.lcserver'}; if (lc($desiredhost) eq 'default') { $desiredhost = undef; } else { - my %home_servers =&Apache::loncommon::get_library_servers($domain); + my %home_servers =&Apache::lonnet::get_servers($domain,'library'); if (! exists($home_servers{$desiredhost})) { $r->print('<font color="#ff0000">'.&mt('Error').':</font>'. &mt('Invalid home server specified')); @@ -683,33 +783,33 @@ sub enroll_single_student { # End of home server selection logic my $amode=''; my $genpwd=''; - if ($ENV{'form.login'} eq 'krb') { + if ($env{'form.login'} eq 'krb') { $amode='krb'; - $amode.=$ENV{'form.krbver'}; - $genpwd=$ENV{'form.krbarg'}; - } elsif ($ENV{'form.login'} eq 'int') { + $amode.=$env{'form.krbver'}; + $genpwd=$env{'form.krbarg'}; + } elsif ($env{'form.login'} eq 'int') { $amode='internal'; - $genpwd=$ENV{'form.intarg'}; - } elsif ($ENV{'form.login'} eq 'loc') { + $genpwd=$env{'form.intarg'}; + } elsif ($env{'form.login'} eq 'loc') { $amode='localauth'; - $genpwd=$ENV{'form.locarg'}; + $genpwd=$env{'form.locarg'}; if (!$genpwd) { $genpwd=" "; } } - my $home = &Apache::lonnet::homeserver($ENV{'form.cuname'}, - $ENV{'form.lcdomain'}); + my $home = &Apache::lonnet::homeserver($env{'form.cuname'}, + $env{'form.lcdomain'}); if ((($amode) && ($genpwd)) || ($home ne 'no_host')) { # Clean out any old roles the student has in this class. - &modifystudent($ENV{'form.lcdomain'},$ENV{'form.cuname'}, - $ENV{'request.course.id'},$ENV{'form.csec'}, + &modifystudent($env{'form.lcdomain'},$env{'form.cuname'}, + $env{'request.course.id'},$env{'form.csec'}, $desiredhost); my $login_result = &Apache::lonnet::modifystudent - ($ENV{'form.lcdomain'},$ENV{'form.cuname'}, - $ENV{'form.cstid'},$amode,$genpwd, - $ENV{'form.cfirst'},$ENV{'form.cmiddle'}, - $ENV{'form.clast'},$ENV{'form.cgen'}, - $ENV{'form.csec'},$enddate, - $startdate,$ENV{'form.forceid'}, - $desiredhost); + ($env{'form.lcdomain'},$env{'form.cuname'}, + $env{'form.cstid'},$amode,$genpwd, + $env{'form.cfirst'},$env{'form.cmiddle'}, + $env{'form.clast'},$env{'form.cgen'}, + $env{'form.csec'},$enddate, + $startdate,$env{'form.forceid'}, + $desiredhost,$env{'form.emailaddress'}); if ($login_result =~ /^ok/) { $r->print($login_result); $r->print("<p> ".&mt('If active, the new role will be available when the student next logs in to LON-CAPA.')."</p>"); @@ -723,21 +823,37 @@ sub enroll_single_student { } else { $r->print(&mt('Invalid login mode or password.').' '); } - $r->print('<b>'.&mt('Unable to enroll').' '.$ENV{'form.cuname'}.'.</b></p>'); + $r->print('<b>'.&mt('Unable to enroll').' '.$env{'form.cuname'}.'.</b></p>'); } } else { $r->print(&mt('Invalid username or domain')); } + $r->print("<p><a href='/adm/dropadd?action=enrollstudent'>".&mt("Enroll another student")."</a></p>"); + if (ref($srcharray) eq 'ARRAY') { + foreach my $item (@{$srcharray},'ccuname','ccdomain') { + $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n"); + } + } + foreach my $item ('sortby','seluname','seludom') { + if (exists($env{'form.'.$item})) { + $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n"); + } + } + $r->print('<input type="hidden" name="phase" value="get_user_info" />'."\n". + '<input type="hidden" name="currstate" value="" />'."\n". + '<input type="hidden" name="prevphase" value="" />'."\n". + '<input type="hidden" name="action" value="enrollstudent" />'."\n". + '<input type="hidden" name="state" value="gotusername" />'); } sub setup_date_selectors { my ($starttime,$endtime,$mode) = @_; if (! defined($starttime)) { $starttime = time; - unless ($mode eq 'createcourse') { - if (exists($ENV{'course.'.$ENV{'request.course.id'}. + 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'}. + $starttime = $env{'course.'.$env{'request.course.id'}. '.default_enrollment_start_date'}; } } @@ -745,9 +861,9 @@ sub setup_date_selectors { 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'}. + if (exists($env{'course.'.$env{'request.course.id'}. '.default_enrollment_end_date'})) { - $endtime = $ENV{'course.'.$ENV{'request.course.id'}. + $endtime = $env{'course.'.$env{'request.course.id'}. '.default_enrollment_end_date'}; } } @@ -758,12 +874,20 @@ sub setup_date_selectors { my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform', 'enddate', $endtime); - if ($mode eq 'createcourse') { + if ($mode eq 'create_enrolldates') { $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs', - 'startdate', + 'startenroll', $starttime); $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs', - 'enddate', + '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); @@ -772,7 +896,7 @@ sub setup_date_selectors { sub get_dates_from_form { my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate'); my $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate'); - if ($ENV{'form.no_end_date'}) { + if ($env{'form.no_end_date'}) { $enddate = 0; } return ($startdate,$enddate); @@ -782,16 +906,20 @@ sub date_setting_table { my ($starttime,$endtime,$mode) = @_; my ($startform,$endform)=&setup_date_selectors($starttime,$endtime,$mode); my $dateDefault = '<nobr>'. - '<input type="checkbox" name="makedatesdefault" /> '. - &mt('make these dates the default for future enrollment'); - if ($mode eq 'createcourse') { + '<label><input type="checkbox" name="makedatesdefault" /> '. + &mt('make these dates the default for future enrollment'). + '</label></nobr>'; + if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') { $dateDefault = ' '; } - my $perpetual = '<nobr><input type="checkbox" name="no_end_date"'; + my $perpetual = '<nobr><label><input type="checkbox" name="no_end_date"'; if (defined($endtime) && $endtime == 0) { $perpetual .= ' checked'; } - $perpetual.= ' /> '.&mt('no ending date').'</nobr>'; + $perpetual.= ' /> '.&mt('no ending date').'</label></nobr>'; + if ($mode eq 'create_enrolldates') { + $perpetual = ' '; + } my $result = ''; $result .= "<table>\n"; $result .= '<tr><td align="right">'.&mt('Starting Date').'</td>'. @@ -807,8 +935,8 @@ sub date_setting_table { sub make_dates_default { my ($startdate,$enddate) = @_; my $result = ''; - my $dom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; - my $crs = $ENV{'course.'.$ENV{'request.course.id'}.'.num'}; + my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $crs = $env{'course.'.$env{'request.course.id'}.'.num'}; my $put_result = &Apache::lonnet::put('environment', {'default_enrollment_start_date'=>$startdate, 'default_enrollment_end_date' =>$enddate},$dom,$crs); @@ -816,7 +944,8 @@ sub make_dates_default { $result .= "Set default start and end dates for course<br />"; # # Refresh the course environment - &Apache::lonnet::coursedescription($ENV{'request.course.id'}); + &Apache::lonnet::coursedescription($env{'request.course.id'}, + {'freshen_cache' => 1}); } else { $result .= &mt('Unable to set default dates for course').":".$put_result. '<br />'; @@ -828,9 +957,23 @@ sub make_dates_default { ## Single student enrollment routines (some of them) ## sub get_student_username_domain_form { - my $r = shift; - my $domform = &Apache::loncommon::select_dom_form - ($ENV{'course.'.$ENV{'request.course.id'}.'.domain'},'cudomain',0); + my ($r,$elements,$response,$srch,$forcenewuser) = @_; + my $loaditems = { + 'onload' => "javascript:setFormElements(document.studentform)", + }; + $r->print(&header(undef,$loaditems)); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.studentform,'','')", + text=>"Single user search"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student', + 'Course_Add_Student')); + my $defdom=$env{'request.role.domain'}; + + my $jscript = &Apache::loncommon::studentbrowser_javascript()."\n". + '<script type="text/javascript">'."\n". + &Apache::lonhtmlcommon::set_form_elements($elements->{'studentform'}). + '</script>'."\n"; + my %lt=&Apache::lonlocal::texthash( 'eos' => "Enroll One Student", 'usr' => "Username", @@ -838,30 +981,49 @@ sub get_student_username_domain_form { 'been' => "Begin Enrollment", ); $r->print(<<END); -<input type="hidden" name="action" value="enrollstudent" /> -<input type="hidden" name="state" value="gotusername" /> +$jscript <h3>$lt{'eos'}</h3> -<table> -<tr><th>$lt{'usr'}:</th> - <td><input type="text" name="cuname" size="15" /></td></tr> -<tr><th>$lt{'dom'}:</th> - <td>$domform</td></tr> -<tr><th> </th> - <td> - <input type="submit" name="Begin Enrollment" value="$lt{'been'}" /> - </td></tr> -</table> END + $r->print($response); + $r->print(&single_user_entry_form($defdom,$srch,$forcenewuser)); return; } +sub single_user_entry_form { + my ($dom,$srch,$forcenewuser) = @_; + my $userpicker = + &Apache::loncommon::user_picker($dom,$srch,$forcenewuser, + 'document.studentform'); + my $srchbutton = &mt('Search'); + my $output = <<"ENDDOCUMENT"; +<input type="hidden" name="action" value="enrollstudent" /> +<input type="hidden" name="state" value="gotusername" /> +<input type="hidden" name="phase" value="get_user_info" /> +$userpicker +<input name="userrole" type="button" value="$srchbutton" onclick="javascript:validateEntry(document.studentform)" /> +ENDDOCUMENT + return $output; +} + sub print_enroll_single_student_form { - my $r=shift; + my ($r,$jscript,$ccuname,$ccdomain,$srch) = @_; + $r->print(&header($jscript)); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.studentform,'','')", + text=>"Single user search"}); + if ($env{'form.phase'} eq 'userpicked') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.studentform,'get_user_info','select')", + text=>"Select user",}); + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.studentform,'$env{'form.phase'}','modify')", + text=>"Set enrollment",}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student', + 'Course_Add_Student')); $r->print("<h3>".&mt('Enroll One Student')."</h3>"); # - my $username = $ENV{'form.cuname'}; - my $domain = $ENV{'form.cudomain'}; - my $home = &Apache::lonnet::homeserver($username,$domain); + my $home = &Apache::lonnet::homeserver($ccuname,$ccdomain); # $new_user flags whether we are creating a new user or using an old one my $new_user = 1; if ($home ne 'no_host') { @@ -871,10 +1033,31 @@ sub print_enroll_single_student_form { my $user_data_html = ''; my $javascript_validations = ''; if ($new_user) { - my $defdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; + my $usertoadd; + my $instsrch = { + srchin => 'instd', + srchby => 'uname', + srchtype => 'exact', + srchterm => $ccuname, + srchdomain => $ccdomain, + }; + if (($instsrch->{'srchterm'} ne '') && ($instsrch->{'srchdomain'} ne '')) { + $usertoadd = $instsrch->{'srchterm'}.':'.$instsrch->{'srchdomain'}; + } + my (%dirsrch_results,%inst_results); + if ($usertoadd) { + if (&Apache::loncreateuser::directorysrch_check($instsrch) eq 'ok') { + %dirsrch_results = &Apache::lonnet::inst_directory_query($instsrch); + if (ref($dirsrch_results{$usertoadd}) eq 'HASH') { + %inst_results = %{$dirsrch_results{$usertoadd}}; + } + } + } + + my $defdom=$env{'course.'.$env{'request.course.id'}.'.domain'}; # Set up authentication forms my ($krbdef,$krbdefdom) = - &Apache::loncommon::get_kerberos_defaults($domain); + &Apache::loncommon::get_kerberos_defaults($ccdomain); $javascript_validations=&javascript_validations('auth',$krbdefdom); my %param = ( formname => 'document.studentform', kerb_def_dom => $krbdefdom, @@ -886,7 +1069,7 @@ sub print_enroll_single_student_form { # # Set up domain selection form my $homeserver_form = ''; - my %servers = &Apache::loncommon::get_library_servers($domain); + my %servers = &Apache::lonnet::get_servers($ccdomain,'library'); $homeserver_form = '<select name="lcserver" size="1">'."\n". '<option value="default" selected>default</option>'."\n"; while (my ($servername,$serverdescription) = each (%servers)) { @@ -905,23 +1088,27 @@ sub print_enroll_single_student_form { 'hs' => "Home Server", 'pswd' => "Password", 'psam' => "Please select an authentication mechanism", + 'mail' => "Email Address" ); + my $authhelp=&Apache::loncommon::help_open_topic('Auth_Options'); $user_data_html = <<END; -<h3>$lt{'udf'} $username\@$domain</h3> +<h3>$lt{'udf'} $ccuname:$ccdomain</h3> <table> -<tr><th>$lt{'fn'}:</th> - <td><input type="text" name="cfirst" size="15"></td></tr> -<tr><th>$lt{'mn'}:</th> - <td><input type="text" name="cmiddle" size="15"></td></tr> -<tr><th>$lt{'ln'}:</th> - <td><input type="text" name="clast" size="15"></td></tr> -<tr><th>$lt{'gen'}:</th> - <td><input type="text" name="cgen" size="5"> </td></tr> -<tr><th>$lt{'hs'}:</th> +<tr><td class="LC_dropadd_labeltext"><label for="cfirst">$lt{'fn'}</label>:</td> + <td><input type="text" name="cfirst" size="15" value="$inst_results{'firstname'}" /></td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="cmiddle">$lt{'mn'}</label>:</td> + <td><input type="text" name="cmiddle" size="15" value="$inst_results{'middlename'}" /></td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="clast">$lt{'ln'}</label>:</td> + <td><input type="text" name="clast" size="15" value="$inst_results{'lastname'}" /></td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="cgen">$lt{'gen'}</label>:</td> + <td><input type="text" name="cgen" size="5" value="$inst_results{'generation'}" /> </td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="lcserver">$lt{'hs'}</label>:</td> <td>$homeserver_form</td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="emailaddress">$lt{'mail'}</label>:</td> + <td><input type="text" name="emailaddress" size="20" value="$inst_results{'permanentemail'}" /></td></tr> </table> <h3>$lt{'pswd'}</h3> -$lt{'psam'} +$lt{'psam'}$authhelp <table> <p> $krbform @@ -933,7 +1120,7 @@ $locform END } else { # User already exists. Do not worry about authentication - my %uenv = &Apache::lonnet::dump('environment',$domain,$username); + my %uenv = &Apache::lonnet::dump('environment',$ccdomain,$ccuname); $javascript_validations = &javascript_validations('noauth'); my %lt=&Apache::lonlocal::texthash( 'udf' => "User Data for", @@ -941,27 +1128,22 @@ END 'mn' => "Middle Name", 'ln' => "Last Name", 'gen' => "Generation", + 'mail' => "Email Address", ); $user_data_html = <<END; -<h3>$lt{'udf'} $username\@$domain</h3> +<h3>$lt{'udf'} $ccuname:$ccdomain</h3> <input type="hidden" name="lcserver" value="default" /> <table> -<tr><th>$lt{'fn'}:</th> - <td> - <input type="text" name="cfirst" value="$uenv{'firstname'}" size="15" /> - </td></tr> -<tr><th>$lt{'mn'}:</th> - <td> - <input type="text" name="cmiddle" value="$uenv{'middlename'}" size="15" /> - </td></tr> -<tr><th>$lt{'ln'}:</th> - <td> - <input type="text" name="clast"value="$uenv{'lastname'}" size="15" /> - </td></tr> -<tr><th>$lt{'gen'}:</th> - <td> - <input type="text" name="cgen" value="$uenv{'generation'}" size="5" /> - </td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="cfirst">$lt{'fn'}</label>:</td> + <td><input type="text" name="cfirst" value="$uenv{'firstname'}" size="15" /></td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="cmiddle">$lt{'mn'}</label>:</td> + <td><input type="text" name="cmiddle" value="$uenv{'middlename'}" size="15" /></td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="clast">$lt{'ln'}</label>:</td> + <td><input type="text" name="clast" value="$uenv{'lastname'}" size="15" /></td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="cgen">$lt{'gen'}</label>:</td> + <td><input type="text" name="cgen" value="$uenv{'generation'}" size="5" /> </td></tr> +<tr><td class="LC_dropadd_labeltext"><label for="emailaddress">$lt{'mail'}</label>:</td> + <td><input type="text" name="emailaddress" value="$uenv{'permanentemail'}" size="20" /></td></tr> </table> END } @@ -969,18 +1151,18 @@ END # Print it all out my %lt=&Apache::lonlocal::texthash( 'cd' => "Course Data", - 'gs' => "Group/Section", + 'gs' => "Section", 'idsn' => "ID/Student Number", 'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)", 'eas' => "Enroll as student", ); $r->print(<<END); <input type="hidden" name="action" value="enrollstudent" /> -<input type="hidden" name="state" value="done" /> -<input type="hidden" name="cuname" value="$username" /> -<input type="hidden" name="lcdomain" value="$domain" /> +<input type="hidden" name="state" value="gotusername" /> +<input type="hidden" name="cuname" value="$ccuname" /> +<input type="hidden" name="lcdomain" value="$ccdomain" /> <script type="text/javascript" language="Javascript"> -function verify(vf) { +function verify(vf,sec_caller) { var founduname=0; var foundpwd=0; var foundname=0; @@ -997,6 +1179,9 @@ function verify(vf) { } if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) { foundsec=1; + if (validate(sec_caller) == "error") { + return; + } } if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) { foundid=1; @@ -1020,20 +1205,34 @@ $user_data_html <h3>$lt{'cd'}</h3> -<p>$lt{'gs'}: <input type="text" name="csec" size="5" /> -<p> -$date_table +<p><label for="csec">$lt{'gs'}</label>: <input type="text" name="csec" size="5" /> </p> +$date_table <h3>$lt{'idsn'}</h3> <p> -$lt{'idsn'}: <input type="text" name="cstid" size="10"> +<label for="cstid">$lt{'idsn'}</label>: <input type="text" name="cstid" size="10" /> </p><p> -<input type="checkbox" name="forceid" value="yes"> +<label> +<input type="checkbox" name="forceid" value="yes" /> $lt{'disn'} +</label> </p><p> -<input type="button" onClick="verify(this.form)" value="$lt{'eas'}"> +<input type="button" onClick="verify(this.form,this.form.csec)" value="$lt{'eas'}" /> </p> END + $r->print('<input type="hidden" name="currstate" value="" />'."\n". + '<input type="hidden" name="phase" value="" />'."\n". + '<input type="hidden" name="prevphase" value="'.$env{'form.phase'}.'" />'."\n"); + if (ref($srch) eq 'HASH') { + foreach my $item (sort(keys(%{$srch}))) { + $r->print('<input type="hidden" name="'.$item.'" value="'.$srch->{$item}.'" />'."\n"); + } + } + foreach my $item ('sortby','seluname','seludom') { + if (exists($env{'form.'.$item})) { + $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n"); + } + } return; } @@ -1041,7 +1240,7 @@ END sub print_drop_menu { my $r=shift; $r->print("<h3>".&mt('Drop Students')."</h3>"); - my $cid=$ENV{'request.course.id'}; + my $cid=$env{'request.course.id'}; my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist(); if (! defined($classlist)) { $r->print(&mt('There are no students currently enrolled.')."\n"); @@ -1054,102 +1253,181 @@ sub print_drop_menu { # ============================================== view classlist sub print_html_classlist { - my $r=shift; - if (! exists($ENV{'form.sortby'})) { - $ENV{'form.sortby'} = 'username'; + my ($r,$mode,$permission) = @_; + if (! exists($env{'form.sortby'})) { + $env{'form.sortby'} = 'username'; } - if ($ENV{'form.Status'} !~ /^(Any|Expired|Active)$/) { - $ENV{'form.Status'} = 'Active'; + if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) { + $env{'form.Status'} = 'Active'; } my $status_select = &Apache::lonhtmlcommon::StatusOptions - ($ENV{'form.Status'},'studentform'); - my $CCL=&mt('Current Class List'); - $r->print(<<END); -<input type="hidden" name="action" value="$ENV{'form.action'}" /> -<input type="hidden" name="state" value="" /> -<p> -<font size="+1">$CCL</font> - -END - if ($ENV{'form.action'} ne 'modifystudent') { - my %lt=&Apache::lonlocal::texthash( - 'ef' => "Excel format", - 'ss' => "Student Status", - ); - $r->print(<<END); -<font size="+1"> -<a href="javascript:document.studentform.state.value='csv';document.studentform.submit();">CSV format</a> - -<a href="javascript:document.studentform.state.value='excel';document.studentform.submit();">$lt{'ef'}</a> -</font> - -$lt{'ss'}: -END + ($env{'form.Status'}); + my $cid =$env{'request.course.id'}; + my $cdom=$env{'course.'.$cid.'.domain'}; + my $cnum=$env{'course.'.$cid.'.num'}; + # + # List course personnel + my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum); + # + if (! defined($env{'form.output'}) || + $env{'form.output'} !~ /^(csv|excel|html)$/ ) { + $env{'form.output'} = 'html'; + } + # + $r->print('<br />'.&Apache::loncommon::start_data_table()); + foreach my $role (sort keys %coursepersonnel) { + next if ($role =~ /^\s*$/); + $r->print(&Apache::loncommon::start_data_table_row(). + '<td>'.$role.'</td><td>'); + foreach my $user (split(',',$coursepersonnel{$role})) { + my ($puname,$pudom)=split(':',$user); + $r->print(' '.&Apache::loncommon::aboutmewrapper( + &Apache::loncommon::plainname($puname, + $pudom), + $puname,$pudom)); + } + $r->print('</td>'.&Apache::loncommon::end_data_table_row()); + } + $r->print(&Apache::loncommon::end_data_table()); + # + # Interface output + $r->print('<input type="hidden" name="action" value="'. + $env{'form.action'}.'" />'); + $r->print("<p>\n"); + if ($env{'form.action'} ne 'modifystudent') { + my %lt=&Apache::lonlocal::texthash('csv' => "CSV", + 'excel' => "Excel", + 'html' => 'HTML'); + my $output_selector = '<select size="1" name="output" >'; + foreach my $outputformat ('html','csv','excel') { + my $option = '<option value="'.$outputformat.'" '; + if ($outputformat eq $env{'form.output'}) { + $option .= 'selected '; + } + $option .='>'.$lt{$outputformat}.'</option>'; + $output_selector .= "\n".$option; + } + $output_selector .= '</select>'; + $r->print('<label>'.&mt('Output Format: [_1]',$output_selector).'</label>'.(' 'x3)); } - $r->print($status_select."</p>\n"); - my $cid=$ENV{'request.course.id'}; + $r->print('<label>'.&mt('Student Status: [_1]',$status_select)."</label>\n"); + $r->print('<input type="submit" value="'.&mt('Update Display').'" />'. + "\n</p>\n"); + # + # Print the classlist + $r->print('<h2>'.&mt('Current Class List').'</h2>'); my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist(); + + if (exists($permission->{'view_section'})) { + my $sec = &Apache::loncoursedata::CL_SECTION(); + foreach my $student (keys(%{$classlist})) { + if ($classlist->{$student}[$sec] ne $permission->{'view_section'}) { + delete($classlist->{$student}); + } + } + } + if (! defined($classlist)) { $r->print(&mt('There are no students currently enrolled.')."\n"); } else { # Print out the available choices - if ($ENV{'form.action'} eq 'modifystudent') { - &show_class_list($r,'view','modify','modifystudent', - $ENV{'form.Status'},$classlist,$keylist); + if ($env{'form.action'} eq 'modifystudent') { + &show_class_list($r,'view','modify', + $env{'form.Status'},$classlist,$keylist); } else { - &show_class_list($r,'view','aboutme','classlist', - $ENV{'form.Status'},$classlist,$keylist); + &show_class_list($r,$env{'form.output'},'aboutme', + $env{'form.Status'},$classlist,$keylist); } } } -# ============================================== view classlist -sub print_formatted_classlist { - my $r=shift; - my $mode = shift; - my $cid=$ENV{'request.course.id'}; - my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist(); - if (! defined($classlist)) { - $r->print(&mt('There are no students currently enrolled.')."\n"); - } else { - &show_class_list($r,$mode,'nolink','csv', - $ENV{'form.Status'},$classlist,$keylist); - } -} - # =================================================== Show student list to drop sub show_class_list { - my ($r,$mode,$linkto,$action,$statusmode,$classlist,$keylist)=@_; - my $cid=$ENV{'request.course.id'}; + my ($r,$mode,$linkto,$statusmode,$classlist,$keylist)=@_; + my $cid=$env{'request.course.id'}; + my $cdom = $env{'course.'.$cid.'.domain'}; + my $cnum = $env{'course.'.$cid.'.num'}; + my ($classgroups) = &Apache::loncoursedata::get_group_memberships( + $classlist,$keylist,$cdom,$cnum); # # Variables for excel output - my ($excel_workbook, $excel_sheet, $excel_filename,$row); + my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format); + # + # Variables for csv output + my ($CSVfile,$CSVfilename); # - my $sortby = $ENV{'form.sortby'}; - if ($sortby !~ /^(username|domain|section|fullname|id)$/) { + my $sortby = $env{'form.sortby'}; + if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end|type)$/) { $sortby = 'username'; } + if (! exists($env{'form.displayphotos'})) { + $env{'form.displayphotos'} = 'off'; + } + my $displayphotos = $env{'form.displayphotos'}; + # Print out header - if ($mode eq 'view') { + unless ($mode eq 'autoenroll') { + $r->print(<<END); +<input type="hidden" name="state" value="$env{'form.state'}" /> +END + } + $r->print(<<END); +<input type="hidden" name="sortby" value="$sortby" /> +<input type="hidden" name="displayphotos" value="$displayphotos" /> +END + if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') { if ($linkto eq 'aboutme') { - $r->print(&mt('Select a user name to view the users personal page.')); + $r->print(&mt("Select a user name to view the user's personal page.")); } elsif ($linkto eq 'modify') { - $r->print(&mt('Select a user name to modify the students information')); + $r->print(&mt("Select a user name to modify the student's information")); } my %lt=&Apache::lonlocal::texthash( - 'usrn' => "username", - 'dom' => "domain", - 'sn' => "student name", - 'sec' => "section", + 'usrn' => "username", + 'dom' => "domain", + 'sn' => "student name", + 'sec' => "section", + 'grp' => "active groups", + 'start' => "start date", + 'end' => "end date", + 'type' => "enroll type/action", + 'email' => "email address", + 'photo' => "photo", ); - $r->print(<<END); - -<input type="hidden" name="sortby" value="$sortby" /> + unless ($mode eq 'autoenroll') { + $r->print(<<END); <input type="hidden" name="sname" value="" /> <input type="hidden" name="sdom" value="" /> +END + } + if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { + $r->print(' +<script type="text/javascript"> +function photowindow(photolink) { + var title = "Photo_Viewer"; + var options = "scrollbars=1,resizable=1,menubar=0"; + options += ",width=240,height=240"; + stdeditbrowser = open(photolink,title,options,"1"); + stdeditbrowser.focus(); +} +</script> + '); + } + $r->print(" <p> -<table border=2> -<tr><th> +".&Apache::loncommon::start_data_table()." +<tr> + "); + if ($mode eq 'autoenroll') { + $r->print(" + <th><a href=\"javascript:document.studentform.sortby.value='type';document.studentform.submit();\">$lt{'type'}</a></th> + "); + } else { + $r->print(" +<th>Count</th> + "); + } + $r->print(<<END); + <th> <a href="javascript:document.studentform.sortby.value='username';document.studentform.submit();">$lt{'usrn'}</a> </th><th> <a href="javascript:document.studentform.sortby.value='domain';document.studentform.submit();">$lt{'dom'}</a> @@ -1159,37 +1437,83 @@ sub show_class_list { <a href="javascript:document.studentform.sortby.value='fullname';document.studentform.submit();">$lt{'sn'}</a> </th><th> <a href="javascript:document.studentform.sortby.value='section';document.studentform.submit();">$lt{'sec'}</a> + </th><th> + <a href="javascript:document.studentform.sortby.value='start';document.studentform.submit();">$lt{'start'}</a> + </th><th> + <a href="javascript:document.studentform.sortby.value='end';document.studentform.submit();">$lt{'end'}</a> + </th><th> + <a href="javascript:document.studentform.sortby.value='groups';document.studentform.submit();">$lt{'grp'}</a> + </th><th> + <a href="javascript:document.studentform.sortby.value='email';document.studentform.submit();">$lt{'email'}</a> </th> -</tr> END + 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'; + } + $r->print(' <th>'."\n".' '. + '<a href="javascript:document.studentform.displayphotos.value='. + "'".$photochg."'".';document.studentform.submit();">'. + $photo_options{$photochg}.'</a> '.$lt{'photo'}."\n". + ' </th>'."\n"); + } + $r->print(" </tr>\n"); } 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("Problems occured in writing the csv file. ". + "This error has been logged. ". + "Please alert your LON-CAPA administrator."); + $CSVfile = undef; + } + # + # Write headers and data to file if($statusmode eq 'Expired') { - $r->print(&mt('Students with expired roles')); + print $CSVfile '"'.&mt('Students with expired roles').'"'."\n"; + } + if($statusmode eq 'Future') { + print $CSVfile '"'.&mt('Students with future roles').'"'."\n"; } if ($statusmode eq 'Any') { - $r->print('"'.join('","',(&mt("username"),&mt("domain"),"ID", - &mt("student name"),&mt("section"),&mt("status"))). - '"'."\n"); + print $CSVfile '"'.join('","',map { + &Apache::loncommon::csv_translate(&mt($_)) + } ("username","domain","ID","student name", + "section","start date","end date","status", + "active groups","email address")) + .'"'."\n"; } else { - $r->print('"'.join('","',(&mt("username"),&mt("domain"),"ID", - &mt("student name"),&mt("section"))).'"'."\n"); + print $CSVfile '"'.join('","',map { + &Apache::loncommon::csv_translate(&mt($_)) + } ("username","domain","ID","student name", + "section","start date","end date", + "active groups","email address")).'"'."\n"; } } elsif ($mode eq 'excel') { # Create the excel spreadsheet - $excel_filename = '/prtspool/'. - $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. - time.'_'.rand(1000000000).'.xls'; - $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'. - $excel_filename); - $excel_workbook->set_tempdir('/home/httpd/perl/tmp'); + ($excel_workbook,$excel_filename,$format) = + &Apache::loncommon::create_workbook($r); + return if (! defined($excel_workbook)); $excel_sheet = $excel_workbook->addworksheet('classlist'); # my $description = 'Class List for '. - $ENV{'course.'.$ENV{'request.course.id'}.'.description'}; - $excel_sheet->write($row++,0,$description); + $env{'course.'.$env{'request.course.id'}.'.description'}; + $excel_sheet->write($row++,0,$description,$format->{'h1'}); # $excel_sheet->write($row++,0,["username","domain","ID", - "student name","section","status"]); + "student name","section", + "start date","end date","status", + "active groups","email address"], + $format->{'bold'}); } # # Sort the students @@ -1198,6 +1522,7 @@ END foreach (@$keylist) { $index{$_} = $i++; } + $index{'groups'} = scalar(@{$keylist}); my $index = $index{$sortby}; my $second = $index{'username'}; my $third = $index{'domain'}; @@ -1208,16 +1533,70 @@ END || lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third]) } (keys(%$classlist)); + my $studentcount = 0; + my $autocount = 0; + my $manualcount = 0; + my $unlockcount = 0; + my $lockcount = 0; foreach my $student (@Sorted_Students) { - my $username = $classlist->{$student}->[$index{'username'}]; - my $domain = $classlist->{$student}->[$index{'domain'}]; - my $section = $classlist->{$student}->[$index{'section'}]; - my $name = $classlist->{$student}->[$index{'fullname'}]; - my $id = $classlist->{$student}->[$index{'id'}]; - my $status = $classlist->{$student}->[$index{'status'}]; + my $sdata = $classlist->{$student}; + my $groups = $classgroups->{$student}; + my $username = $sdata->[$index{'username'}]; + my $domain = $sdata->[$index{'domain'}]; + my $section = $sdata->[$index{'section'}]; + my $active_groups; + if (ref($groups->{active}) eq 'HASH') { + $active_groups = join(', ',keys(%{$groups->{'active'}})); + } + my $name = $sdata->[$index{'fullname'}]; + my $id = $sdata->[$index{'id'}]; + my $status = $sdata->[$index{'status'}]; next if (($statusmode ne 'Any') && ($status ne $statusmode)); - if ($mode eq 'view') { - $r->print("<tr>\n <td>\n "); + my $start = $sdata->[$index{'start'}]; + my $end = $sdata->[$index{'end'}]; + my $type = $sdata->[$index{'type'}]; + + my %emails = &Apache::loncommon::getemails($username,$domain); + my $email; + if ($emails{'permanentemail'} =~ /\S/) { + $email = $emails{'permanentemail'}; + } + + if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') { + 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); + } + $r->print(&Apache::loncommon::start_data_table_row()); + if ($mode eq 'autoenroll') { + my $lockedtype = $sdata->[$index{'lockedtype'}]; + $studentcount++; + my $cellentry; + if ($type eq 'auto') { + $cellentry = '<b>'.&mt('auto').'</b> <label><input type="checkbox" name="chgauto" value="'.$username.':'.$domain.'" /> Change</label>'; + $autocount ++; + } else { + $cellentry = '<table border="0" cellspacing="0"><tr><td rowspan="2"><b>'.&mt('manual').'</b></td><td><nobr><label><input type="checkbox" name="chgmanual" value="'.$username.':'.$domain.'" /> Change</label></nobr></td></tr><tr><td><nobr>'; + $manualcount ++; + if ($lockedtype) { + $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$username.':'.$domain.'" /> '.&mt('Unlock').'</label>'; + $unlockcount ++; + } else { + $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$username.':'.$domain.'" /> '.&mt('Lock').'</label>'; + $lockcount ++; + } + $cellentry .= '</nobr></td></tr></table>'; + } + $r->print("<td>$cellentry<td>\n "); + } else { + $r->print("<td>".(++$studentcount)."</td><td>\n "); + } if ($linkto eq 'nothing') { $r->print($username); } elsif ($linkto eq 'aboutme') { @@ -1239,33 +1618,84 @@ END <td>$id</td> <td>$name</td> <td>$section</td> -</tr> -END + <td>$start</td> + <td>$end</td> + <td>$active_groups</td> + <td>$email</td> +END + if ($env{'course.'.$env{'request.course.id'}. + '.internal.showphoto'}) { + if ($displayphotos eq 'on') { + my $imgurl = + &Apache::lonnet::retrievestudentphoto($domain, + $username,'gif', + 'thumbnail'); + + $r->print(' <td align="right"><a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($domain,$username,'jpg')."'".')"><img src="'.$imgurl.'" border="1"></a></td>'); + } else { + $r->print(' <td> </td> '); + } + } + $r->print(&Apache::loncommon::end_data_table_row()); } elsif ($mode eq 'csv') { + next if (! defined($CSVfile)); # no need to bother with $linkto + 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 @line = (); - foreach ($username,$domain,$id,$name,$section) { + foreach ($username,$domain,$id,$name,$section,$start,$end) { push @line,&Apache::loncommon::csv_translate($_); } if ($statusmode eq 'Any') { push @line,&Apache::loncommon::csv_translate($status); } - my $tmp = $"; - $" = '","'; - $r->print("\"@line\"\n"); - $" = $tmp; + push @line,&Apache::loncommon::csv_translate($active_groups); + push @line,&Apache::loncommon::csv_translate($email); + print $CSVfile '"'.join('","',@line).'"'."\n"; } elsif ($mode eq 'excel') { - $excel_sheet->write($row++,0,[$username,$domain,$id, - $name,$section,$status]); + $excel_sheet->write($row,0,[$username,$domain,$id, + $name,$section]); + my $col = 5; + foreach my $time ($start,$end) { + if (defined($time) && $time != 0) { + $excel_sheet->write($row,$col++, + &Apache::lonstathelpers::calc_serial($time), + $format->{'date'}); + } else { + $excel_sheet->write($row,$col++,'none'); + } + } + $excel_sheet->write($row,$col++,$status); + $excel_sheet->write($row,$col++,$active_groups); + $excel_sheet->write($row,$col++,$email); + $row++; } } - if ($mode eq 'view') { - $r->print('</table><br>'); + if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') { + $r->print(&Apache::loncommon::end_data_table().'<br />'); } elsif ($mode eq 'excel') { $excel_workbook->close(); $r->print('<p><a href="'.$excel_filename.'">'. &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n"); + } elsif ($mode eq 'csv') { + close($CSVfile); + $r->print('<a href="'.$CSVfilename.'">'. + &mt('Your CSV file').'</a> is ready for download.'. + "\n"); + $r->rflush(); + } + if ($mode eq 'autoenroll') { + return ($studentcount,$autocount,$manualcount,$lockcount,$unlockcount); } + return; } @@ -1276,21 +1706,21 @@ sub print_modify_student_form { my $r = shift(); &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['sdom','sname']); - my $sname = $ENV{'form.sname'}; - my $sdom = $ENV{'form.sdom'}; - my $sortby = $ENV{'form.sortby'}; + my $sname = $env{'form.sname'}; + my $sdom = $env{'form.sdom'}; + my $sortby = $env{'form.sortby'}; # determine the students name information my %info=&Apache::lonnet::get('environment', ['firstname','middlename', - 'lastname','generation','id'], - $sdom, $sname); + 'lastname','generation','id', + 'permanentemail'], $sdom, $sname); my ($tmp) = keys(%info); if ($tmp =~ /^(con_lost|error|no_such_host)/i) { $r->print('<font color="#ff0000" size="+2">'.&mt('Error').'</font>'. '<p>'. &mt('Unable to retrieve environment data for').' '.$sname. &mt('in domain').' '.$sdom.'</p><p>'. - &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p></body></html>'); + &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p>'.&Apache::loncommon::end_page()); return; } # determine the students starting and ending times and section @@ -1300,12 +1730,33 @@ sub print_modify_student_form { $r->print('<p>'.$starttime.'</p>'); return; } + # # Deal with date forms + my $current_date_description = ''; + my $textdate = ''; + + if (! defined($starttime) || $starttime == 0) { + $current_date_description = &mt('Current Starting Date: not set'). + '<br />'; + } else { + $current_date_description = + &mt('Current Starting Date: [_1]', + &Apache::lonlocal::locallocaltime($starttime)).'<br />'; + } + if (! defined($endtime) || $endtime == 0) { + $current_date_description.= &mt('Current Ending Date: not set'). + '<br />'; + } else { + $current_date_description.= + &mt('Current Ending Date: [_1]', + &Apache::lonlocal::locallocaltime($endtime)).'<br />'; + + } my $date_table = &date_setting_table($starttime,$endtime); # - if (! exists($ENV{'form.Status'}) || - $ENV{'form.Status'} !~ /^(Any|Expired|Active)$/) { - $ENV{'form.Status'} = 'crap'; + if (! exists($env{'form.Status'}) || + $env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) { + $env{'form.Status'} = 'crap'; } # Make sure student is enrolled in course my %lt=&Apache::lonlocal::texthash( @@ -1316,12 +1767,25 @@ sub print_modify_student_form { 'mn' => "Middle", 'ln' => "Last", 'gen' => "Generation", + 'email' => "E-mail address", 'sid' => "Student ID", 'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)", 'sec' => "Section", 'sm' => "Submit Modifications", ); - $r->print(<<END); +# Check if section name is valid + my $section_check = §ion_check_js(); + $r->print(<<"END"); +<script type="text/javascript"> +$section_check +function secverify(formname,caller) { + if (validate(caller) == "error") { + return; + } else { + formname.submit(); + } +} +</script> <p> <font size="+1"> $lt{'odcc'} @@ -1332,10 +1796,9 @@ $lt{'odcc'} <input type="hidden" name="action" value="modifystudent" /> <input type="hidden" name="state" value="done" /> <input type="hidden" name="sortby" value="$sortby" /> -<input type="hidden" name="Status" value="$ENV{'form.Status'}" /> - -<h2>$lt{'mef'} $info{'firstname'} $info{'middlename'} -$info{'lastname'} $info{'generation'}, $sname\@$sdom</h2> +<input type="hidden" name="Status" value="$env{'form.Status'}" /> +<h3>$lt{'mef'} $info{'firstname'} $info{'middlename'} +$info{'lastname'} $info{'generation'}, $sname:$sdom</h3> <p> <b>$lt{'sn'}</b> <table> @@ -1347,17 +1810,22 @@ $info{'lastname'} $info{'generation'}, $ <input type="text" name="generation" value="$info{'generation'}" /></td></tr> </table> </p><p> -<b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12"/> +<b>$lt{'email'}</b>: <input type="text" name="permanentemail" value="$info{'permanentemail'}" size="30" /> </p><p> -<input type="checkbox" name="forceid" > +<b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12" /> +</p><p> +<label> +<input type="checkbox" name="forceid" /> $lt{'disn'} +</label> </p><p> -<b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="4"/> +<b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="14" /> </p> +<p>$current_date_description</p> <p>$date_table</p> -<input type="submit" value="$lt{'sm'}" /> -</body></html> +<input type="button" value="$lt{'sm'}" onClick="secverify(this.form,this.form.section)" /> END + $r->print(&Apache::loncommon::end_page()); return; } @@ -1365,53 +1833,54 @@ END # modify a single students section # sub modify_single_student { - my $r = shift; + my ($r) = @_; # # Remove non alphanumeric values from the section - $ENV{'form.section'} =~ s/\W//g; + $env{'form.section'} =~ s/\W//g; # # Do the date defaults first my ($starttime,$endtime) = &get_dates_from_form(); - if ($ENV{'form.makedatesdefault'}) { + if ($env{'form.makedatesdefault'}) { $r->print(&make_dates_default($starttime,$endtime)); } # Get the 'sortby' and 'Status' variables so the user goes back to their # previous screen - my $sortby = $ENV{'form.sortby'}; - my $status = $ENV{'form.Status'}; + my $sortby = $env{'form.sortby'}; + my $status = $env{'form.Status'}; # # We always need this information - my $slogin = $ENV{'form.slogin'}; - my $sdom = $ENV{'form.sdomain'}; + my $slogin = $env{'form.slogin'}; + my $sdom = $env{'form.sdomain'}; # # Get the old data my %old=&Apache::lonnet::get('environment', ['firstname','middlename', - 'lastname','generation','id'], - $sdom, $slogin); + 'lastname','generation','id', + 'permanentemail'],$sdom, $slogin); $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin, - $ENV{'request.course.id'}); + $env{'request.course.id'}); my ($tmp) = keys(%old); if ($tmp =~ /^(con_lost|error|no_such_host)/i) { - $r->print(&mt('There was an error determining the environment values for')." $slogin \@ $sdom."); + $r->print(&mt('There was an error determining the environment values for')." $slogin : $sdom."); return; } undef $tmp; # # Get the new data - my $firstname = $ENV{'form.firstname'}; - my $middlename = $ENV{'form.middlename'}; - my $lastname = $ENV{'form.lastname'}; - my $generation = $ENV{'form.generation'}; - my $section = $ENV{'form.section'}; - my $courseid = $ENV{'request.course.id'}; - my $sid = $ENV{'form.id'}; + my $firstname = $env{'form.firstname'}; + my $middlename = $env{'form.middlename'}; + my $lastname = $env{'form.lastname'}; + my $generation = $env{'form.generation'}; + my $permanentemail = $env{'form.permanentemail'}; + my $section = $env{'form.section'}; + my $courseid = $env{'request.course.id'}; + my $sid = $env{'form.id'}; my $displayable_starttime = localtime($starttime); my $displayable_endtime = localtime($endtime); # # check for forceid override if ((defined($old{'id'})) && ($old{'id'} ne '') && - ($sid ne $old{'id'}) && (! exists($ENV{'form.forceid'}))) { + ($sid ne $old{'id'}) && (! exists($env{'form.forceid'}))) { $r->print("<font color=\"ff0000\">".&mt('You changed the students id but did not disable the ID change safeguard. The students id will not be changed.')."</font>"); $sid = $old{'id'}; } @@ -1427,50 +1896,91 @@ sub modify_single_student { 'mn' => "Middle name", 'ln' => "Last name", 'gen' => "Generation", + 'em' => "E-mail address", 'sec' => "Section", 'ri' => "Role Information", 'st' => "Start Time", 'et' => "End Time", ); $r->print(<<END); - <h2>$lt{'mdu'} $slogin \@ $sdom </h2> -<h3>$lt{'si'}</h3> -<table rules="rows" border="1" cellpadding="3" > -<tr> - <th> $lt{'fd'} </th> - <th> $lt{'ov'} </th> - <th> $lt{'nv'} </th> -</tr> -<tr> - <td> <b>$lt{'fn'}</b> </td> - <td> $old{'firstname'} </td> - <td> $firstname </td> -</tr><tr> - <td> <b>$lt{'mn'}</b> </td> - <td> $old{'middlename'} </td> - <td> $middlename </td> -</tr><tr> - <td> <b>$lt{'ln'}</b> </td> - <td> $old{'lastname'} </td> - <td> $lastname </td> -</tr><tr> - <td> <b>$lt{'gen'}</b> </td> - <td> $old{'generation'} </td> - <td> $generation </td> -</tr><tr> - <td> <b>ID</b> </td> - <td> $old{'id'} </td> - <td> $sid </td> -</tr><tr> - <td> <b>$lt{'sec'}</b> </td> - <td> $old{'section'} </td> - <td> $section</td> -</tr> -</table> -<h3>$lt{'ri'}</h3> + <h3>$lt{'mdu'} $slogin:$sdom </h3> +END + $r->print(<<END); <table> -<tr><td align="right"><b>$lt{'st'}:</b></td><td> $displayable_starttime </td></tr> -<tr><td align="right"><b>$lt{'et'}:</b></td><td> $displayable_endtime </td></tr> + <tr> + <td> + <table class="LC_nested_outer"> + <tr> + <th>$lt{si}</th> + </tr> + <tr> + <td> + <table class="LC_nested"> + <tr class="LC_info_row"> + <td class="LC_left_item"> $lt{'fd'} </td> + <td class="LC_left_item"> $lt{'ov'} </td> + <td class="LC_left_item"> $lt{'nv'} </td> + </tr> + <tr class="LC_odd_row"> + <td class="LC_left_item"> <b>$lt{'fn'}</b> </td> + <td class="LC_left_item"> $old{'firstname'} </td> + <td class="LC_left_item"> $firstname </td> + </tr> + <tr> + <td class="LC_left_item"> <b>$lt{'mn'}</b> </td> + <td class="LC_left_item"> $old{'middlename'} </td> + <td class="LC_left_item"> $middlename </td> + </tr> + <tr class="LC_odd_row"> + <td class="LC_left_item"> <b>$lt{'ln'}</b> </td> + <td class="LC_left_item"> $old{'lastname'} </td> + <td class="LC_left_item"> $lastname </td> + </tr> + <tr> + <td class="LC_left_item"> <b>$lt{'gen'}</b> </td> + <td class="LC_left_item"> $old{'generation'} </td> + <td class="LC_left_item"> $generation </td> + </tr> + <tr class="LC_odd_row"> + <td class="LC_left_item"> <b>ID</b> </td> + <td class="LC_left_item"> $old{'id'} </td> + <td class="LC_left_item"> $sid </td> + </tr> + <tr> + <td class="LC_left_item"> <b>$lt{'em'}</b> </td> + <td class="LC_left_item"> $old{'permanentemail'} </td> + <td class="LC_left_item"> $permanentemail </td> + <tr class="LC_odd_row"> + <td> <b>$lt{'sec'}</b> </td> + <td> $old{'section'} </td> + <td> $section</td> + </tr> + </table> + </td> + </tr> + </table> + <br /> + <table class="LC_nested_outer"> + <tr> + <th>$lt{'ri'}</th> + </tr> + <tr> + <td> + <table class="LC_nested"> + <tr class="LC_odd_row"> + <td class="LC_left_item"><b>$lt{'st'}:</b></td> + <td class="LC_right_item"> $displayable_starttime </td> + </tr> + <tr> + <td class="LC_left_item"><b>$lt{'et'}:</b></td> + <td class="LC_right_item"> $displayable_endtime </td> + </tr> + </table> + </td> + </tr> + </table> + </td> + </tr> </table> <p> END @@ -1478,14 +1988,18 @@ END # Send request(s) to modify data (final undef is for 'desiredhost', # which is a moot point because the student already has an account. my $modify_section_results = &modifystudent($sdom,$slogin, - $ENV{'request.course.id'}, + $env{'request.course.id'}, $section,undef); if ($modify_section_results !~ /^ok/) { $r->print(&mt('An error occured during the attempt to change the section for this student.')."<br />"); } my $roleresults = &Apache::lonnet::modifystudent ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname, - $generation,$section,$endtime,$starttime,$ENV{'form.forceid'}); + $generation,$section,$endtime,$starttime,$env{'form.forceid'}, + undef,$permanentemail); + if ($old{'permanentemail'} ne $permanentemail) { + &Apache::loncommon::flush_email_cache($slogin,$sdom); + } if ($roleresults eq 'refused' ) { $r->print(&mt('Your request to change the role information for this student was refused. You do not appear to have sufficient authority to change student information.')); } elsif ($roleresults !~ /ok/) { @@ -1493,8 +2007,8 @@ END &mt('The error reported was')." ". $roleresults); &Apache::lonnet::logthis("londropadd:failed attempt to modify student". - " data for ".$slogin." \@ ".$sdom." by ". - $ENV{'user.name'}." \@ ".$ENV{'user.domain'}. + " data for ".$slogin." : ".$sdom." by ". + $env{'user.name'}." : ".$env{'user.domain'}. ":".$roleresults); } else { # everything is okay! $r->print(&mt('Student information updated successfully.')." <br />". @@ -1507,15 +2021,16 @@ END <input type="hidden" name="sortby" value="$sortby" /> <input type="hidden" name="Status" value="$status" /> <a href="javascript:document.studentform.submit();">$Masd</a> -</body></html> END + $r->print(&Apache::loncommon::end_page()); return; } sub get_enrollment_data { my ($sname,$sdomain) = @_; - my $courseid = $ENV{'request.course.id'}; - $courseid =~ s:_:/:g; + my $courseid = $env{'request.course.id'}; + my $cdom = $env{'course.'.$courseid.'.domain'}; + my $cnum = $env{'course.'.$courseid.'.num'}; my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname); my ($tmp) = keys(%roles); # Bail out if we were unable to get the students roles @@ -1525,7 +2040,7 @@ sub get_enrollment_data { my $section = ''; my $count = scalar(keys(%roles)); while (my ($course,$role) = each(%roles)) { - if ($course=~ /^\/$courseid\/*\s*(\w+)*_st$/ ) { + if ($course=~m{^/\Q$cdom\E/\Q$cnum\E/*\s*(\w+)*_st$} ) { # # Get active role $section=$1; @@ -1573,15 +2088,19 @@ which describes the order elements are s ################################################# sub show_drop_list { my ($r,$classlist,$keylist,$nosort)=@_; - my $cid=$ENV{'request.course.id'}; - if (! exists($ENV{'form.sortby'})) { + my $cid=$env{'request.course.id'}; + if (! exists($env{'form.sortby'})) { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['sortby']); } - my $sortby = $ENV{'form.sortby'}; - if ($sortby !~ /^(username|domain|section|fullname|id)$/) { + my $sortby = $env{'form.sortby'}; + if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) { $sortby = 'username'; } + my $cdom = $env{'course.'.$cid.'.domain'}; + my $cnum = $env{'course.'.$cid,'.num'}; + my ($classgroups) = &Apache::loncoursedata::get_group_memberships( + $classlist,$keylist,$cdom,$cnum); # my $action = "drop"; $r->print(<<END); @@ -1603,15 +2122,17 @@ function uncheckAll(field) { <input type="hidden" name="phase" value="four"> END +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) { - my %lt=&Apache::lonlocal::texthash( - 'usrn' => "username", - 'dom' => "domain", - 'sn' => "student name", - 'sec' => "section", - ); + $r->print(&Apache::loncommon::start_data_table()); $r->print(<<END); -<table border=2> <tr> <th> </th> <th>$lt{'usrn'}</th> @@ -1619,18 +2140,15 @@ END <th>ID</th> <th>$lt{'sn'}</th> <th>$lt{'sec'}</th> + <th>$lt{'start'}</th> + <th>$lt{'end'}</th> + <th>$lt{'groups'}</th> </tr> END } else { - my %lt=&Apache::lonlocal::texthash( - 'usrn' => "username", - 'dom' => "domain", - 'sn' => "student name", - 'sec' => "section", - ); + $r->print(&Apache::loncommon::start_data_table()); $r->print(<<END); -<table border=2> <tr><th> </th> <th> <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a> @@ -1642,6 +2160,12 @@ END <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a> </th><th> <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a> + </th><th> + <a href="/adm/dropadd?action=$action&sortby=start">$lt{'start'}</a> + </th><th> + <a href="/adm/dropadd?action=$action&sortby=end">$lt{'end'}</a> + </th><th> + <a href="/adm/dropadd?action=$action&sortby=groups">$lt{'groups'}</a> </th> </tr> END @@ -1653,6 +2177,7 @@ END foreach (@$keylist) { $index{$_} = $i++; } + $index{'groups'} = scalar(@$keylist); my $index = $index{$sortby}; my $second = $index{'username'}; my $third = $index{'domain'}; @@ -1665,27 +2190,48 @@ END } (keys(%$classlist)); foreach my $student (@Sorted_Students) { my $error; - my $username = $classlist->{$student}->[$index{'username'}]; - my $domain = $classlist->{$student}->[$index{'domain'}]; - my $section = $classlist->{$student}->[$index{'section'}]; - my $name = $classlist->{$student}->[$index{'fullname'}]; - my $id = $classlist->{$student}->[$index{'id'}]; - my $status = $classlist->{$student}->[$index{'status'}]; + my $sdata = $classlist->{$student}; + my $username = $sdata->[$index{'username'}]; + my $domain = $sdata->[$index{'domain'}]; + my $section = $sdata->[$index{'section'}]; + my $name = $sdata->[$index{'fullname'}]; + my $id = $sdata->[$index{'id'}]; + my $start = $sdata->[$index{'start'}]; + my $end = $sdata->[$index{'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 $status = $sdata->[$index{'status'}]; next if ($status ne 'Active'); # + $r->print(&Apache::loncommon::start_data_table_row()); $r->print(<<"END"); -<tr> <td><input type="checkbox" name="droplist" value="$student"></td> <td>$username</td> <td>$domain</td> <td>$id</td> <td>$name</td> <td>$section</td> -</tr> + <td>$start</td> + <td>$end</td> + <td>$active_groups</td> END + $r->print(&Apache::loncommon::end_data_table_row()); } - $r->print('</table><br>'); - my %lt=&Apache::lonlocal::texthash( + $r->print(&Apache::loncommon::end_data_table().'<br />'); + %lt=&Apache::lonlocal::texthash( 'dp' => "Drop Students", 'ca' => "check all", 'ua' => "uncheck all", @@ -1713,15 +2259,15 @@ sub print_first_courselist_upload_form { $str .= "<p>\n"; $str .= '<input type="submit" name="fileupload" value="'. &mt('Upload class list').'">'."\n"; - $str .= '<input type="checkbox" name="noFirstLine" /> '. - &mt('Ignore First Line')."</p>\n"; + $str .= '<label><input type="checkbox" name="noFirstLine" /> '. + &mt('Ignore First Line')."</label></p>\n"; $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List", &mt("How do I create a class list from a spreadsheet")). "<br />\n"; $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV", &mt("How do I create a CSV file from a spreadsheet")). "<br />\n"; - $str .= "</body>\n</html>\n"; + $str .= &Apache::loncommon::end_page(); $r->print($str); return; } @@ -1731,54 +2277,72 @@ sub upfile_drop_add { my $r=shift; &Apache::loncommon::load_tmp_file($r); my @studentdata=&Apache::loncommon::upfile_record_sep(); - if($ENV{'form.noFirstLine'}){shift(@studentdata);} - my @keyfields = split(/\,/,$ENV{'form.keyfields'}); - my $cid = $ENV{'request.course.id'}; + if($env{'form.noFirstLine'}){shift(@studentdata);} + my @keyfields = split(/\,/,$env{'form.keyfields'}); + my $cid = $env{'request.course.id'}; 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}; + 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]; + $fields{$env{'form.f'.$i}}=$keyfields[$i]; } } # + # Store the field choices away + foreach my $field (qw/username names + fname mname lname gen id sec ipwd email/) { + $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' }); + + # my ($startdate,$enddate) = &get_dates_from_form(); - if ($ENV{'form.makedatesdefault'}) { + if ($env{'form.makedatesdefault'}) { $r->print(&make_dates_default($startdate,$enddate)); } # Determine domain and desired host (home server) - my $domain=$ENV{'form.lcdomain'}; - my $desiredhost = $ENV{'form.lcserver'}; + my $domain=$env{'form.lcdomain'}; + my $desiredhost = $env{'form.lcserver'}; if (lc($desiredhost) eq 'default') { $desiredhost = undef; } else { - my %home_servers = &Apache::loncommon::get_library_servers($domain); + my %home_servers = &Apache::lonnet::get_servers($domain,'library'); if (! exists($home_servers{$desiredhost})) { $r->print('<font color="#ff0000">'.&mt('Error').'</font>'. &mt('Invalid home server specified')); - $r->print("</body>\n</html>\n"); + $r->print(&Apache::loncommon::end_page()); return; } } # Determine authentication mechanism my $amode = ''; my $genpwd = ''; - if ($ENV{'form.login'} eq 'krb') { + if ($env{'form.login'} eq 'krb') { $amode='krb'; - $amode.=$ENV{'form.krbver'}; - $genpwd=$ENV{'form.krbarg'}; - } elsif ($ENV{'form.login'} eq 'int') { + $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'}; + if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) { + $genpwd=$env{'form.intarg'}; } - } elsif ($ENV{'form.login'} eq 'loc') { + } elsif ($env{'form.login'} eq 'loc') { $amode='localauth'; - if ((defined($ENV{'form.locarg'})) && ($ENV{'form.locarg'})) { - $genpwd=$ENV{'form.locarg'}; + if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) { + $genpwd=$env{'form.locarg'}; } } if ($amode =~ /^krb/) { @@ -1789,7 +2353,8 @@ sub upfile_drop_add { $amode = ''; # This causes the loop below to be skipped } } - unless (($domain=~/\W/) || ($amode eq '')) { + if ( $domain eq &LONCAPA::clean_domain($domain) + && ($amode ne '')) { ####################################### ## Enroll Students ## ####################################### @@ -1797,6 +2362,8 @@ sub upfile_drop_add { my $count=0; my $flushc=0; my %student=(); + # Get information about course groups + my %curr_groups = &Apache::longroup::coursegroups(); # Get new classlist foreach (@studentdata) { my %entries=&Apache::loncommon::record_sep($_); @@ -1821,7 +2388,8 @@ sub upfile_drop_add { $gen=$entries{$fields{'gen'}}; } } - if ($entries{$fields{'username'}}=~/\W/) { + if ($entries{$fields{'username'}} + ne &LONCAPA::clean_username($entries{$fields{'username'}})) { $r->print('<br />'. &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]', $entries{$fields{'username'}},$fname,$mname,$lname,$gen). @@ -1837,6 +2405,17 @@ sub upfile_drop_add { } # remove non alphanumeric values from section $sec =~ s/\W//g; + if ($sec eq "none" || $sec eq 'all') { + $r->print('<br />'. + &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a reserved word.', + $username,$sec,$fname,$mname,$lname,$gen)); + next; + } elsif (($sec ne '') && (exists($curr_groups{$sec}))) { + $r->print('<br />'. + &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a course group. Section names and group names must be distinct.', + $username,$sec,$fname,$mname,$lname,$gen)); + next; + } # determine student id number my $id=''; if (defined($fields{'id'})) { @@ -1869,13 +2448,13 @@ sub upfile_drop_add { \$lname,\$gen,\$sec) { $$_ =~ s/(\s+$|^\s+)//g; } - if ($password || $ENV{'form.login'} eq 'loc') { + if ($password || $env{'form.login'} eq 'loc') { &modifystudent($domain,$username,$cid,$sec, $desiredhost); my $reply=&Apache::lonnet::modifystudent ($domain,$username,$id,$amode,$password, $fname,$mname,$lname,$gen,$sec,$enddate, - $startdate,$ENV{'form.forceid'},$desiredhost, + $startdate,$env{'form.forceid'},$desiredhost, $email); if ($reply ne 'ok') { $reply =~ s/^error://; @@ -1906,7 +2485,7 @@ sub upfile_drop_add { ##################################### # Drop students # ##################################### - if ($ENV{'form.fullup'} eq 'yes') { + if ($env{'form.fullup'} eq 'yes') { $r->print('<h3>'.&mt('Dropping Students')."</h3>\n"); # Get current classlist my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist(); @@ -1934,16 +2513,11 @@ sub upfile_drop_add { sub drop_student_list { my $r=shift; my $count=0; - my @droplist; - if (ref($ENV{'form.droplist'})) { - @droplist = @{$ENV{'form.droplist'}}; - } else { - @droplist = ($ENV{'form.droplist'}); - } + my @droplist = &Apache::loncommon::get_env_multiple('form.droplist'); foreach (@droplist) { my ($uname,$udom)=split(/\:/,$_); # drop student - my $result = &modifystudent($udom,$uname,$ENV{'request.course.id'}); + my $result = &modifystudent($udom,$uname,$env{'request.course.id'}); if ($result eq 'ok' || $result eq 'ok:') { $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>'); $count++; @@ -1957,6 +2531,59 @@ sub drop_student_list { $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count); } +sub section_check_js { + my $groupslist; + my %curr_groups = &Apache::longroup::coursegroups(); + if (%curr_groups) { + $groupslist = join('","',sort(keys(%curr_groups))); + } + 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<groups.length; k++) { + if (secname == groups[k]) { + alert("'"+secname+"' may not be used as the name for a section, as it is the name of a course group.\\nSection names and group names must be distinct. Please choose a different section name."); + return 'error'; + } + } + } + return 'ok'; +} +END +} + +sub get_permission { + my %permission; + $permission{'view'} = + &Apache::lonnet::allowed('vcl',$env{'request.course.id'}); + 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'}; + } + } + + $permission{'enrl'} = + &Apache::lonnet::allowed('cst',$env{'request.course.id'}); + + $permission{'grp_view'} = + &Apache::lonnet::allowed('vcg',$env{'request.course.id'}); + $permission{'grp_manage'} = + &Apache::lonnet::allowed('mdg',$env{'request.course.id'}); + my $allowed = 0; + foreach my $perm (values(%permission)) { + if ($perm) { $allowed=1; last; } + } + return (\%permission,$allowed); +} + ################################################################### ################################################################### @@ -2000,36 +2627,56 @@ sub handler { } &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['action','state']); + + &Apache::lonhtmlcommon::clear_breadcrumbs(); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/dropadd", + text=>"Enrollment Manager", + faq=>9,bug=>'Instructor Interface',}); # Needs to be in a course - if (! (($ENV{'request.course.fn'}) && - (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'})))) { - # Not in a course, or not allowed to modify parms - $ENV{'user.error.msg'}= - "/adm/dropadd:cst:0:0:Cannot drop or add students"; + if (! ($env{'request.course.fn'})) { + # Not in a course + $env{'user.error.msg'}= + "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ". + "or drop or add students"; return HTTP_NOT_ACCEPTABLE; } # + + my ($permission,$allowed) = &get_permission(); + + if (!$allowed) { + $env{'user.error.msg'}= + "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ". + "or drop or add students"; + return HTTP_NOT_ACCEPTABLE; + } + + # # Only output the header information if they did not request csv format # - if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) { - $r->content_type('text/csv'); - } else { - # Start page - &Apache::loncommon::content_type($r,'text/html'); - $r->send_http_header; - $r->print(&header()); - } + # Start page + &Apache::loncommon::content_type($r,'text/html'); + $r->send_http_header; # # Main switch on form.action and form.state, as appropriate - if (! exists($ENV{'form.action'})) { - &print_main_menu($r); - } elsif ($ENV{'form.action'} eq 'upload') { - if (! exists($ENV{'form.state'})) { + if (! exists($env{'form.action'})) { + $r->print(&header()); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager')); + my $action = &print_main_menu($r,$permission); + } elsif ($env{'form.action'} eq 'upload' && $permission->{'enrl'}) { + $r->print(&header()); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/dropadd?action=upload&state=', + text=>"Upload Classlist"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Upload Classlist', + 'Course_Create_Class_List')); + if (! exists($env{'form.state'})) { &print_first_courselist_upload_form($r); - } elsif ($ENV{'form.state'} eq 'got_file') { + } elsif ($env{'form.state'} eq 'got_file') { &print_upload_manager_form($r); - } elsif ($ENV{'form.state'} eq 'enrolling') { - if ($ENV{'form.datatoken'}) { + } elsif ($env{'form.state'} eq 'enrolling') { + if ($env{'form.datatoken'}) { &upfile_drop_add($r); } else { # Hmmm, this is an error @@ -2037,58 +2684,142 @@ sub handler { } else { &print_first_courselist_upload_form($r); } - } elsif ($ENV{'form.action'} eq 'drop') { - if (! exists($ENV{'form.state'})) { + } elsif ($env{'form.action'} eq 'drop' && $permission->{'enrl'}) { + $r->print(&header()); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/dropadd?action=drop', + text=>"Drop Students"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students', + 'Course_Drop_Student')); + if (! exists($env{'form.state'})) { &print_drop_menu($r); - } elsif ($ENV{'form.state'} eq 'done') { + } elsif ($env{'form.state'} eq 'done') { &drop_student_list($r); } else { &print_drop_menu($r); } - } elsif ($ENV{'form.action'} eq 'enrollstudent') { - if (! exists($ENV{'form.state'})) { - &get_student_username_domain_form($r); - } elsif ($ENV{'form.state'} eq 'gotusername') { - &print_enroll_single_student_form($r); - } elsif ($ENV{'form.state'} eq 'enrolling') { - &enroll_single_student($r); + } elsif ($env{'form.action'} eq 'enrollstudent' && $permission->{'enrl'}) { + my @search = ('srchterm','srchby','srchin','srchtype','srchdomain'); + my ($jsback,$elements) = &Apache::loncreateuser::crumb_utilities(); + my $jscript = '<script type="text/javascript">'.$jsback.'</script>'; + if ($env{'form.state'} eq 'gotusername') { + my $srch; + foreach my $item (@search) { + $srch->{$item} = $env{'form.'.$item}; + } + if ($env{'form.phase'} eq 'get_user_info') { + my ($currstate,$response,$forcenewuser,$results) = + &Apache::loncreateuser::user_search_result($srch); + if ($currstate eq 'select') { + $r->print(&header()); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.usersrchform,'','')", + text=>"Single user search"}, + {href=>"javascript:backPage(document.usersrchform,'get_user_info','select')", + text=>"Select User",}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student', + 'Course_Add_Student')); + &Apache::loncreateuser::print_user_selection_page($r, + $response,$srch,$results,'enrollstudent',\@search); + } elsif ($currstate eq 'modify') { + my ($ccuname,$ccdomain); + if (($srch->{'srchby'} eq 'uname') && + ($srch->{'srchtype'} eq 'exact')) { + $ccuname = $srch->{'srchterm'}; + $ccdomain= $srch->{'srchdomain'}; + } else { + my @matchedunames = keys(%{$results}); + ($ccuname,$ccdomain) = split(/:/,$matchedunames[0]); + } + $ccuname =&LONCAPA::clean_username($ccuname); + $ccdomain=&LONCAPA::clean_domain($ccdomain); + &print_enroll_single_student_form($r,$jscript,$ccuname, + $ccdomain,$srch,$response); + } elsif ($currstate eq 'query') { + $r->print(&header($jscript)); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.studentform,'','')", + text=>"Single user search"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student', + 'Course_Add_Student')); + &Apache::loncreateuser::print_user_query_page($r,'enrollstudent'); + } else { + &get_student_username_domain_form($r,$elements,$response, + $srch,$forcenewuser); + } + } elsif ($env{'form.phase'} eq 'userpicked') { + my $ccuname = &LONCAPA::clean_username($env{'form.seluname'}); + my $ccdomain = &LONCAPA::clean_domain($env{'form.seludom'}); + &print_enroll_single_student_form($r,$jscript,$ccuname, + $ccdomain,$srch); + } else { + &get_student_username_domain_form($r,$elements); + } + } elsif ($env{'form.state'} eq 'enrolling') { + $r->print(&header($jscript)); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.studentform,'','')", + text=>"Single user search"}); + if ($env{'form.prevphase'} eq 'userpicked') { + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.studentform,'get_user_info','select')", + text=>"Select user",}); + } + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:backPage(document.studentform,'$env{'form.prevphase'}','modify')", + text=>"Set enrollment",}, + {href=>"javascript:backPage(document.studentform,$env{'form.phase'},'')", + text=>"Result",}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student', + 'Course_Add_Student')); + &enroll_single_student($r,\@search); } else { - &get_student_username_domain_form($r); + &get_student_username_domain_form($r,$elements); } - } elsif ($ENV{'form.action'} eq 'classlist') { - if (! exists($ENV{'form.state'})) { - &print_html_classlist($r); - } elsif ($ENV{'form.state'} eq 'csv') { - &print_formatted_classlist($r,'csv'); - } elsif ($ENV{'form.state'} eq 'excel') { - &print_formatted_classlist($r,'excel'); + } elsif ($env{'form.action'} eq 'classlist' && $permission->{'view'}) { + $r->print(&header()); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/dropadd?action=classlist', + text=>"View Classlist"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('View Classlist', + 'Course_View_Class_List')); + if (! exists($env{'form.state'})) { + &print_html_classlist($r,undef,$permission); + } elsif ($env{'form.state'} eq 'csv') { + &print_html_classlist($r,'csv',$permission); + } elsif ($env{'form.state'} eq 'excel') { + &print_html_classlist($r,'excel',$permission); } else { - &print_html_classlist($r); + &print_html_classlist($r,undef,$permission); } - } elsif ($ENV{'form.action'} eq 'modifystudent') { - if (! exists($ENV{'form.state'})) { - &print_html_classlist($r); - } elsif ($ENV{'form.state'} eq 'selected') { + } elsif ($env{'form.action'} eq 'modifystudent' && $permission->{'enrl'}) { + $r->print(&header()); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>'/adm/dropadd?action=modifystudent', + text=>"Modify Student Data"}); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Modify Student Data', + 'Course_Modify_Student_Data')); + if (! exists($env{'form.state'})) { + &print_html_classlist($r,undef,$permission); + } elsif ($env{'form.state'} eq 'selected') { &print_modify_student_form($r); - } elsif ($ENV{'form.state'} eq 'done') { + } elsif ($env{'form.state'} eq 'done') { &modify_single_student($r); } else { - &print_html_classlist($r); + &print_html_classlist($r,undef,$permission); } } else { # We should not end up here, but I guess it is possible &Apache::lonnet::logthis("Undetermined state in londropadd.pm. ". - "form.action = ".$ENV{'form.action'}. + "form.action = ".$env{'form.action'}. "Someone should fix this."); - &print_main_menu($r); + $r->print(&header()); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager')); + &print_main_menu($r,$permission); } # # Finish up - if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) { - $r->print("\n"); - } else { - $r->print('</form></body></html>'); - } + $r->print('</form>'.&Apache::loncommon::end_page()); return OK; }