Annotation of loncom/interface/londropadd.pm, revision 1.157

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to drop and add students in courses 
                      3: #
1.157   ! albertel    4: # $Id: londropadd.pm,v 1.156 2007/03/03 01:33:21 albertel Exp $
1.17      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.1       www        28: #
1.50      matthew    29: ###############################################################
1.82      www        30: ##############################################################
1.1       www        31: 
                     32: package Apache::londropadd;
                     33: 
                     34: use strict;
1.127     albertel   35: use Apache::lonnet;
1.24      albertel   36: use Apache::loncommon();
1.50      matthew    37: use Apache::lonhtmlcommon();
1.1       www        38: use Apache::Constants qw(:common :http REDIRECT);
1.60      matthew    39: use Spreadsheet::WriteExcel;
1.110     matthew    40: use Apache::lonstathelpers();
1.86      www        41: use Apache::lonlocal;
1.143     raeburn    42: use Apache::longroup;
1.152     albertel   43: use LONCAPA();
1.1       www        44: 
1.50      matthew    45: ###############################################################
                     46: ###############################################################
1.10      www        47: sub header {
1.138     albertel   48:     my $start_page=&Apache::loncommon::start_page('Enrollment Manager');
1.27      matthew    49:     return(<<ENDHEAD);
1.138     albertel   50: $start_page
1.40      matthew    51: <form method="post" enctype="multipart/form-data"  
                     52:       action="/adm/dropadd" name="studentform">
1.1       www        53: ENDHEAD
1.10      www        54: }
                     55: 
1.50      matthew    56: ###############################################################
                     57: ###############################################################
                     58: # Drop student from all sections of a course, except optional $csec
1.26      matthew    59: sub modifystudent {
1.33      matthew    60:     my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;
1.26      matthew    61:     # if $csec is undefined, drop the student from all the courses matching
                     62:     # this one.  If $csec is defined, drop them from all other sections of 
                     63:     # this course and add them to section $csec
1.151     albertel   64:     my $cdom = $env{'course.'.$courseid.'.domain'};
                     65:     my $cnum = $env{'course.'.$courseid.'.num'};
1.26      matthew    66:     my %roles = &Apache::lonnet::dump('roles',$udom,$unam);
                     67:     my ($tmp) = keys(%roles);
                     68:     # Bail out if we were unable to get the students roles
1.35      matthew    69:     return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.26      matthew    70:     # Go through the roles looking for enrollment in this course
1.35      matthew    71:     my $result = '';
1.26      matthew    72:     foreach my $course (keys(%roles)) {
1.150     albertel   73:         if ($course=~m{^/\Q$cdom\E/\Q$cnum\E(?:\/)*(?:\s+)*(\w+)*\_st$}) {
1.26      matthew    74:             # We are in this course
1.25      matthew    75:             my $section=$1;
1.150     albertel   76:             $section='' if ($course eq "/$cdom/$cnum".'_st');
1.87      matthew    77:             if (defined($csec) && $section eq $csec) {
1.71      matthew    78:                 $result .= 'ok:';
                     79:             } elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) {
1.27      matthew    80:                 my (undef,$end,$start)=split(/\_/,$roles{$course});
1.25      matthew    81:                 my $now=time;
1.143     raeburn    82:                 # if this is an active role
1.27      matthew    83:                 if (!($start && ($now<$start)) || !($end && ($now>$end))) {
1.25      matthew    84:                     my $reply=&Apache::lonnet::modifystudent
1.70      matthew    85:                         # dom  name  id mode pass     f     m     l     g
                     86:                         ($udom,$unam,'',  '',  '',undef,undef,undef,undef,
1.33      matthew    87:                          $section,time,undef,undef,$desiredhost);
1.35      matthew    88:                     $result .= $reply.':';
1.25      matthew    89:                 }
1.10      www        90:             }
                     91:         }
1.20      harris41   92:     }
1.35      matthew    93:     if ($result eq '') {
1.62      matthew    94:         $result = 'Unable to find section for this student';
1.37      matthew    95:     } else {
                     96:         $result =~ s/(ok:)+/ok/g;
1.35      matthew    97:     }
                     98:     return $result;
1.10      www        99: }
                    100: 
1.50      matthew   101: ###############################################################
                    102: ###############################################################
                    103: # build a domain and server selection form
1.31      matthew   104: sub domain_form {
                    105:     my ($defdom) = @_;
                    106:     # Set up domain and server selection forms
                    107:     #
                    108:     # Get the domains
1.156     albertel  109:     my @domains = &Apache::lonnet::all_domains();
1.31      matthew   110:     # build up the menu information to be passed to 
                    111:     # &Apache::loncommon::linked_select_forms
                    112:     my %select_menus;
                    113:     foreach my $dom (@domains) {
                    114:         # set up the text for this domain
                    115:         $select_menus{$dom}->{'text'}= $dom;
                    116:         # we want a choice of 'default' as the default in the second menu
                    117:         $select_menus{$dom}->{'default'}= 'default';
                    118:         $select_menus{$dom}->{'select2'}->{'default'} = 'default';
                    119:         # Now build up the other items in the second menu
1.157   ! albertel  120:         my %servers = &Apache::lonnet::get_servers($dom,'library');
1.31      matthew   121:         foreach my $server (keys(%servers)) {
                    122:             $select_menus{$dom}->{'select2'}->{$server} 
                    123:                                             = "$server $servers{$server}";
                    124:         }
                    125:     }
                    126:     my $result  = &Apache::loncommon::linked_select_forms
                    127:         ('studentform',' with home server ',$defdom,
                    128:          'lcdomain','lcserver',\%select_menus);
                    129:     return $result;
                    130: }
                    131: 
1.50      matthew   132: ###############################################################
                    133: ###############################################################
                    134: #  Menu Phase One
                    135: sub print_main_menu {
1.132     raeburn   136:     my ($r,$enrl_permission,$view_permission,$grp_manage_permission,
                    137:         $grp_view_permission)=@_;
1.121     matthew   138:     #
1.150     albertel  139:     my $cid =$env{'request.course.id'};
                    140:     my $cdom=$env{'course.'.$cid.'.domain'};
                    141:     my $cnum=$env{'course.'.$cid.'.num'};
1.121     matthew   142:     my @menu = 
                    143:         ( 
1.122     matthew   144:           { text => 'Upload a class list', 
1.121     matthew   145:             help => 'Course_Create_Class_List',
                    146:             action => 'upload',
                    147:             permission => $enrl_permission,
                    148:             },
                    149:           { text => 'Enroll a single student', 
                    150:             help => 'Course_Add_Student',
                    151:             action => 'enrollstudent',
                    152:             permission => $enrl_permission,
                    153:             },
                    154:           { text => 'Modify student data', 
                    155:             help => 'Course_Modify_Student_Data',
                    156:             action => 'modifystudent',
                    157:             permission => $enrl_permission,
                    158:             },
                    159:           { text => 'View Class List', 
                    160:             help => 'Course_View_Class_List',
                    161:             action => 'classlist',
                    162:             permission => $view_permission,
                    163:             },
                    164:           { text => 'Drop Students', 
                    165:             help => 'Course_Drop_Student',
                    166:             action => 'drop',
                    167:             permission => $enrl_permission,
                    168:             },
                    169:           { text => 'Automated Enrollment Manager', 
                    170:             permission => &Apache::lonnet::auto_run($cnum,$cdom),
                    171:             url  => '/adm/populate',
                    172:             },
1.145     albertel  173:           { text => 'Create a new group',
                    174:             help => 'Course_Create_Group',
                    175:             permission => $grp_manage_permission,
                    176:             url => '/adm/coursegroups?refpage=enrl&action=create',
                    177:             },
                    178:           { text => 'Modify an existing group',
                    179:             help => 'Course_Modify_Group',
                    180:             permission => $grp_manage_permission,
                    181:             url => '/adm/coursegroups?refpage=enrl&action=modify',
                    182:             },
1.153     raeburn   183:           { text => 'Delete an existing group',
                    184:             help => 'Course_Delete_Group',
                    185:             permission => $grp_manage_permission,
                    186:             url => '/adm/coursegroups?refpage=enrl&action=delete',
                    187:             },
                    188:           { text => 'Re-enable a deleted group',
                    189:             help => 'Course_Reenable_Group',
                    190:             permission => $grp_manage_permission,
                    191:             url => '/adm/coursegroups?refpage=enrl&action=reenable',
                    192:             },
1.145     albertel  193:           { text => 'Enter an existing group',
                    194:             help => 'Course_Display_Group',
                    195:             permission => $grp_view_permission,
                    196:             url => '/adm/coursegroups?refpage=enrl&action=view',
                    197:             },
1.121     matthew   198:           );
                    199:     my $menu_html = '';
                    200:     foreach my $menu_item (@menu) {
                    201:         next if (! $menu_item->{'permission'});
                    202:         $menu_html.='<p>';
                    203:         $menu_html.='<font size="+1">';
                    204:         if (exists($menu_item->{'url'})) {
                    205:             $menu_html.=qq{<a href="$menu_item->{'url'}">};
                    206:         } else {
                    207:             $menu_html.=
                    208:                 qq{<a href="/adm/dropadd?action=$menu_item->{'action'}">};
                    209:         }
                    210:         $menu_html.= &mt($menu_item->{'text'}).'</a></font>';
                    211:         if (exists($menu_item->{'help'})) {
                    212:             $menu_html.=
                    213:                 &Apache::loncommon::help_open_topic($menu_item->{'help'});
                    214:         }
                    215:         $menu_html.='</p>'.$/;
1.113     raeburn   216:     }
1.121     matthew   217:     $r->print($menu_html);
                    218:     return;
1.10      www       219: }
                    220: 
1.50      matthew   221: ###############################################################
                    222: ###############################################################
1.89      matthew   223: sub hidden_input {
                    224:     my ($name,$value) = @_;
                    225:     return '<input type="hidden" name="'.$name.'" value="'.$value.'" />'."\n";
                    226: }
                    227: 
1.50      matthew   228: sub print_upload_manager_header {
1.23      albertel  229:     my ($r,$datatoken,$distotal,$krbdefdom)=@_;
1.24      albertel  230:     my $javascript;
1.99      matthew   231:     #
1.127     albertel  232:     if (! exists($env{'form.upfile_associate'})) {
                    233:         $env{'form.upfile_associate'} = 'forward';
1.50      matthew   234:     }
1.127     albertel  235:     if ($env{'form.associate'} eq 'Reverse Association') {
                    236:         if ( $env{'form.upfile_associate'} ne 'reverse' ) {
                    237:             $env{'form.upfile_associate'} = 'reverse';
1.50      matthew   238:         } else {
1.127     albertel  239:             $env{'form.upfile_associate'} = 'forward';
1.50      matthew   240:         }
                    241:     }
1.127     albertel  242:     if ($env{'form.upfile_associate'} eq 'reverse') {
1.50      matthew   243: 	$javascript=&upload_manager_javascript_reverse_associate();
1.24      albertel  244:     } else {
1.50      matthew   245: 	$javascript=&upload_manager_javascript_forward_associate();
1.24      albertel  246:     }
1.99      matthew   247:     #
                    248:     # Deal with restored settings
                    249:     my $password_choice = '';
1.127     albertel  250:     if (exists($env{'form.ipwd_choice'}) &&
                    251:         $env{'form.ipwd_choice'} ne '') {
1.99      matthew   252:         # If a column was specified for password, assume it is for an
                    253:         # internal password.  This is a bug waiting to be filed (could be
                    254:         # local or krb auth instead of internal) but I do not have the 
                    255:         # time to mess around with this now.
                    256:         $password_choice = 'int';        
                    257:     }
                    258:     #
                    259:     my $javascript_validations=&javascript_validations('auth',$krbdefdom,
                    260:                                     $password_choice);
1.149     albertel  261:     my $checked=(($env{'form.noFirstLine'})?' checked="checked" ':'');
1.88      matthew   262:     $r->print('<h3>'.&mt('Uploading Class List')."</h3>\n".
                    263:               "<hr>\n".
                    264:               '<h3>'.&mt('Identify fields')."</h3>\n");
                    265:     $r->print("<p>\n".
                    266:               &mt('Total number of records found in file: [_1].',$distotal).
                    267:               "\n".
                    268:               "</p><hr>\n");
1.94      sakharuk  269:     $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 is insufficient to enroll students in your class.')."<hr>\n");
1.89      matthew   270:     $r->print(&hidden_input('action','upload').
                    271:               &hidden_input('state','got_file').
                    272:               &hidden_input('associate','').
                    273:               &hidden_input('datatoken',$datatoken).
1.127     albertel  274:               &hidden_input('fileupload',$env{'form.fileupload'}).
                    275:               &hidden_input('upfiletype',$env{'form.upfiletype'}).
                    276:               &hidden_input('upfile_associate',$env{'form.upfile_associate'}));
1.89      matthew   277:     $r->print('<input type="button" value="Reverse Association" '.
                    278:               'name="'.&mt('Reverse Association').'" '.
                    279:               'onClick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />');
1.148     banghart  280:     $r->print('<label><input type="checkbox" name="noFirstLine"'.$checked.'/>'.
1.131     albertel  281:               &mt('Ignore First Line').'</label>');
1.89      matthew   282:     $r->print("<hr />\n".
                    283:               '<script type="text/javascript" language="Javascript">'."\n".
                    284:               $javascript."\n".$javascript_validations.'</script>');
1.24      albertel  285: }
                    286: 
1.50      matthew   287: ###############################################################
                    288: ###############################################################
1.24      albertel  289: sub javascript_validations {
1.96      raeburn   290:     my ($mode,$krbdefdom,$curr_authtype,$curr_authfield)=@_;
1.89      matthew   291:     my $authheader;
                    292:     if ($mode eq 'auth') {
                    293:         my %param = ( formname => 'studentform',
1.99      matthew   294:                       kerb_def_dom => $krbdefdom,
                    295:                       curr_authtype => $curr_authtype);
1.89      matthew   296:         $authheader = &Apache::loncommon::authform_header(%param);
1.91      raeburn   297:     } elsif ($mode eq 'createcourse') {
                    298:         my %param = ( formname => 'ccrs',
1.99      matthew   299:                   kerb_def_dom => $krbdefdom,
                    300:                       curr_authtype => $curr_authtype );
1.91      raeburn   301:         $authheader = &Apache::loncommon::authform_header(%param);
1.96      raeburn   302:     } elsif ($mode eq 'modifycourse') {
                    303:         my %param = ( formname => 'cmod',
                    304:                   kerb_def_dom => $krbdefdom,
                    305:                   mode => 'modifycourse',
                    306:                   curr_authtype => $curr_authtype,
                    307:                   curr_autharg => $curr_authfield );
                    308:         $authheader = &Apache::loncommon::authform_header(%param);
1.89      matthew   309:     }
1.96      raeburn   310: 
1.91      raeburn   311:     
1.89      matthew   312:     my %alert = &Apache::lonlocal::texthash
                    313:         (username => 'You need to specify the username field.',
                    314:          authen   => 'You must choose an authentication type.',
                    315:          krb      => 'You need to specify the Kerberos domain.',
                    316:          ipass    => 'You need to specify the initial password.',
                    317:          name     => 'The optional name field was not specified.',
                    318:          snum     => 'The optional student number field was not specified.',
1.142     raeburn   319:          section  => 'The optional section field was not specified.', 
1.89      matthew   320:          email    => 'The optional email address field was not specified.',
                    321:          continue => 'Continue enrollment?',
                    322:          );
                    323:     
                    324: #    my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
                    325:     my $function_name =(<<END);
1.73      www       326: function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {
1.89      matthew   327: END
1.97      raeburn   328:     my $auth_checks;
1.96      raeburn   329:     if ($mode eq 'createcourse') {
                    330:         $auth_checks .= (<<END);
1.97      raeburn   331:     if (vf.autoadds[0].checked == true) {
1.96      raeburn   332:         if (current.radiovalue == null || current.radiovalue == 'nochange') {
                    333:             alert('$alert{'authen'}');
                    334:             return;
                    335:         }
                    336:     }
                    337: END
                    338:     } else {
1.91      raeburn   339:         $auth_checks .= (<<END);
1.97      raeburn   340:     var foundatype=0;
1.3       www       341:     if (founduname==0) {
1.89      matthew   342: 	alert('$alert{'username'}');
1.3       www       343:         return;
                    344:     }
1.61      matthew   345:     // alert('current.radiovalue = '+current.radiovalue);
1.119     albertel  346:     if (current.radiovalue == null || current.radiovalue == '' || current.radiovalue == 'nochange') {
1.28      matthew   347:         // They did not check any of the login radiobuttons.
1.89      matthew   348:         alert('$alert{'authen'}');
1.28      matthew   349:         return;
                    350:     }
1.96      raeburn   351: END
                    352:     }
1.97      raeburn   353:     if ($mode eq 'createcourse') {
                    354:         $auth_checks .= "
                    355:     if ( (vf.autoadds[0].checked == true) &&
                    356:          (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') ) {
                    357: ";
                    358:     } elsif ($mode eq 'modifycourse') {
                    359:         $auth_checks .= " 
                    360:     if (vf.elements[current.argfield].value == null || vf.elements[current.argfield].value == '') {
                    361: ";
                    362:     }
1.96      raeburn   363:     if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
1.97      raeburn   364:         $auth_checks .= (<<END);
                    365:         var alertmsg = '';
                    366:         switch (current.radiovalue) {
                    367:             case 'krb':
                    368:                 alertmsg = '$alert{'krb'}';
                    369:                 break;
                    370:             default:
                    371:                 alertmsg = '';
1.96      raeburn   372:         }
1.97      raeburn   373:         if (alertmsg != '') {
                    374:             alert(alertmsg);
                    375:             return;
1.96      raeburn   376:         }
                    377:     }
                    378: END
                    379:     } else {
                    380:         $auth_checks .= (<<END);
1.28      matthew   381:     foundatype=1;
1.29      matthew   382:     if (current.argfield == null || current.argfield == '') {
1.28      matthew   383:         var alertmsg = '';
1.29      matthew   384:         switch (current.value) {
1.28      matthew   385:             case 'krb': 
1.89      matthew   386:                 alertmsg = '$alert{'krb'}';
1.28      matthew   387:                 break;
                    388:             case 'loc':
                    389:             case 'fsys':
1.89      matthew   390:                 alertmsg = '$alert{'ipass'}';
1.28      matthew   391:                 break;
                    392:             case 'fsys':
                    393:                 alertmsg = '';
                    394:                 break;
                    395:             default: 
                    396:                 alertmsg = '';
1.3       www       397:         }
1.28      matthew   398:         if (alertmsg != '') {
                    399:             alert(alertmsg);
1.3       www       400:             return;
                    401:         }
                    402:     }
1.89      matthew   403: END
1.96      raeburn   404:     }
1.142     raeburn   405:     my $section_checks;
1.91      raeburn   406:     my $optional_checks = '';
1.96      raeburn   407:     if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
1.91      raeburn   408:         $optional_checks = (<<END);
                    409:     vf.submit();
                    410: }
                    411: END
                    412:     } else {
1.142     raeburn   413:         $section_checks = &section_check_js();
1.91      raeburn   414:         $optional_checks = (<<END);
1.89      matthew   415:     var message='';
                    416:     if (foundname==0) { 
                    417:         message='$alert{'name'}';
1.24      albertel  418:     }
1.89      matthew   419:     if (foundid==0) { 
                    420:         if (message!='') { 
                    421:             message+='\\n'; 
                    422:         }
                    423:         message+='$alert{'snum'}';
                    424:     }
                    425:     if (foundsec==0) {
                    426:         if (message!='') {
                    427:             message+='\\n';
                    428:         } 
                    429:         message+='$alert{'section'}';
                    430:     }
                    431:     if (foundemail==0) {
                    432:         if (message!='') {
                    433:             message+='\\n';
                    434:         }
                    435:         message+='$alert{'email'}';
1.74      matthew   436:     }
                    437:     if (message!='') {
1.89      matthew   438:         message+= '\\n$alert{'continue'}';
                    439:         if (confirm(message)) {
                    440:             vf.state.value='enrolling';
                    441:             vf.submit();
                    442:         }
1.74      matthew   443:     } else {
1.89      matthew   444:         vf.state.value='enrolling';
                    445:         vf.submit();
1.74      matthew   446:     }
                    447: }
1.89      matthew   448: END
1.91      raeburn   449:     }
1.89      matthew   450:     my $result = $function_name;
1.96      raeburn   451:     if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse')  ) {
1.89      matthew   452:         $result .= $auth_checks;
                    453:     }
1.142     raeburn   454:     $result .= $optional_checks."\n".$section_checks;
1.96      raeburn   455:     if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse')  ) {
1.89      matthew   456:         $result .= $authheader;
                    457:     }
                    458:     return $result;
1.74      matthew   459: }
                    460: 
1.50      matthew   461: ###############################################################
                    462: ###############################################################
                    463: sub upload_manager_javascript_forward_associate {
1.24      albertel  464:     return(<<ENDPICK);
1.142     raeburn   465: function verify(vf,sec_caller) {
1.24      albertel  466:     var founduname=0;
                    467:     var foundpwd=0;
                    468:     var foundname=0;
                    469:     var foundid=0;
                    470:     var foundsec=0;
1.73      www       471:     var foundemail=0;
1.24      albertel  472:     var tw;
                    473:     for (i=0;i<=vf.nfields.value;i++) {
                    474:         tw=eval('vf.f'+i+'.selectedIndex');
                    475:         if (tw==1) { founduname=1; }
                    476:         if ((tw>=2) && (tw<=6)) { foundname=1; }
                    477:         if (tw==7) { foundid=1; }
                    478:         if (tw==8) { foundsec=1; }
                    479:         if (tw==9) { foundpwd=1; }
1.73      www       480:         if (tw==10) { foundemail=1; }
1.24      albertel  481:     }
1.73      www       482:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail);
1.24      albertel  483: }
                    484: 
1.49      matthew   485: //
                    486: // vf = this.form
                    487: // tf = column number
                    488: //
                    489: // values of nw
                    490: //
                    491: // 0 = none
                    492: // 1 = username
                    493: // 2 = names (lastname, firstnames)
                    494: // 3 = fname (firstname)
                    495: // 4 = mname (middlename)
                    496: // 5 = lname (lastname)
                    497: // 6 = gen   (generation)
                    498: // 7 = id
                    499: // 8 = section
                    500: // 9 = ipwd  (password)
1.73      www       501: // 10 = email address
                    502: 
1.24      albertel  503: function flip(vf,tf) {
                    504:    var nw=eval('vf.f'+tf+'.selectedIndex');
                    505:    var i;
1.49      matthew   506:    // make sure no other columns are labeled the same as this one
1.24      albertel  507:    for (i=0;i<=vf.nfields.value;i++) {
                    508:       if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
                    509:           eval('vf.f'+i+'.selectedIndex=0;')
                    510:       }
                    511:    }
1.49      matthew   512:    // If we set this to 'lastname, firstnames', clear out all the ones
                    513:    // set to 'fname','mname','lname','gen' (3,4,5,6) currently.
1.24      albertel  514:    if (nw==2) {
                    515:       for (i=0;i<=vf.nfields.value;i++) {
                    516:          if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
                    517:              (eval('vf.f'+i+'.selectedIndex')<=6)) {
                    518:              eval('vf.f'+i+'.selectedIndex=0;')
                    519:          }
                    520:       }
                    521:    }
1.49      matthew   522:    // If we set this to one of 'fname','mname','lname','gen' (3,4,5,6),
                    523:    // clear out any that are set to 'lastname, firstnames' (2)
1.24      albertel  524:    if ((nw>=3) && (nw<=6)) {
                    525:       for (i=0;i<=vf.nfields.value;i++) {
                    526:          if (eval('vf.f'+i+'.selectedIndex')==2) {
                    527:              eval('vf.f'+i+'.selectedIndex=0;')
                    528:          }
                    529:       }
                    530:    }
1.49      matthew   531:    // If we set the password, make the password form below correspond to 
                    532:    // the new value.
1.24      albertel  533:    if (nw==9) {
1.28      matthew   534:        changed_radio('int',document.studentform);
                    535:        set_auth_radio_buttons('int',document.studentform);
                    536:        vf.intarg.value='';
                    537:        vf.krbarg.value='';
1.24      albertel  538:        vf.locarg.value='';
                    539:    }
                    540: }
                    541: 
                    542: function clearpwd(vf) {
                    543:     var i;
                    544:     for (i=0;i<=vf.nfields.value;i++) {
                    545:         if (eval('vf.f'+i+'.selectedIndex')==9) {
                    546:             eval('vf.f'+i+'.selectedIndex=0;')
                    547:         }
                    548:     }
                    549: }
                    550: 
                    551: ENDPICK
                    552: }
                    553: 
1.50      matthew   554: ###############################################################
                    555: ###############################################################
                    556: sub upload_manager_javascript_reverse_associate {
1.24      albertel  557:     return(<<ENDPICK);
1.142     raeburn   558: function verify(vf,sec_caller) {
1.24      albertel  559:     var founduname=0;
                    560:     var foundpwd=0;
                    561:     var foundname=0;
                    562:     var foundid=0;
                    563:     var foundsec=0;
                    564:     var tw;
                    565:     for (i=0;i<=vf.nfields.value;i++) {
                    566:         tw=eval('vf.f'+i+'.selectedIndex');
                    567:         if (i==0 && tw!=0) { founduname=1; }
                    568:         if (((i>=1) && (i<=5)) && tw!=0 ) { foundname=1; }
                    569:         if (i==6 && tw!=0) { foundid=1; }
                    570:         if (i==7 && tw!=0) { foundsec=1; }
                    571:         if (i==8 && tw!=0) { foundpwd=1; }
                    572:     }
                    573:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
                    574: }
                    575: 
                    576: function flip(vf,tf) {
                    577:    var nw=eval('vf.f'+tf+'.selectedIndex');
                    578:    var i;
                    579:    // picked the all one one name field, reset the other name ones to blank
                    580:    if (tf==1 && nw!=0) {
                    581:       for (i=2;i<=5;i++) {
                    582:          eval('vf.f'+i+'.selectedIndex=0;')
                    583:       }
                    584:    }
                    585:    //picked one of the piecewise name fields, reset the all in
                    586:    //one field to blank
                    587:    if ((tf>=2) && (tf<=5) && (nw!=0)) {
                    588:       eval('vf.f1.selectedIndex=0;')
                    589:    }
                    590:    // intial password specified, pick internal authentication
                    591:    if (tf==8 && nw!=0) {
1.28      matthew   592:        changed_radio('int',document.studentform);
                    593:        set_auth_radio_buttons('int',document.studentform);
                    594:        vf.krbarg.value='';
                    595:        vf.intarg.value='';
1.24      albertel  596:        vf.locarg.value='';
                    597:    }
                    598: }
                    599: 
                    600: function clearpwd(vf) {
                    601:     var i;
                    602:     if (eval('vf.f8.selectedIndex')!=0) {
                    603:         eval('vf.f8.selectedIndex=0;')
                    604:     }
                    605: }
1.2       www       606: ENDPICK
1.23      albertel  607: }
1.10      www       608: 
1.50      matthew   609: ###############################################################
                    610: ###############################################################
                    611: sub print_upload_manager_footer {
1.23      albertel  612:     my ($r,$i,$keyfields,$defdom,$today,$halfyear)=@_;
1.64      albertel  613: 
                    614:     my ($krbdef,$krbdefdom) =
                    615:         &Apache::loncommon::get_kerberos_defaults($defdom);
                    616:     my %param = ( formname => 'document.studentform',
                    617:                   kerb_def_dom => $krbdefdom,
                    618:                   kerb_def_auth => $krbdef
                    619:                   );
1.127     albertel  620:     if (exists($env{'form.ipwd_choice'}) &&
                    621:         defined($env{'form.ipwd_choice'}) &&
                    622:         $env{'form.ipwd_choice'} ne '') {
1.99      matthew   623:         $param{'curr_authtype'} = 'int';
                    624:     }
1.28      matthew   625:     my $krbform = &Apache::loncommon::authform_kerberos(%param);
                    626:     my $intform = &Apache::loncommon::authform_internal(%param);
                    627:     my $locform = &Apache::loncommon::authform_local(%param);
1.31      matthew   628:     my $domform = &domain_form($defdom);
1.68      matthew   629:     my $date_table = &date_setting_table();
1.90      matthew   630:     my $Str = "</table>\n";
                    631:     $Str .= &hidden_input('nfields',$i);
                    632:     $Str .= &hidden_input('keyfields',$keyfields);
                    633:     $Str .= '<h3>'.&mt('Login Type')."</h3>\n";
                    634:     $Str .= "<p>\n".
                    635:         &mt('Note: this will not take effect if the user already exists').
1.130     www       636: 	&Apache::loncommon::help_open_topic('Auth_Options').
1.90      matthew   637:         "</p><p>\n";
                    638:     $Str .= $krbform."\n</p><p>\n".
                    639:         $intform."\n</p><p>\n".
                    640:         $locform."\n</p>\n";
                    641:     $Str .= '<h3>'.&mt('LON-CAPA Domain for Students')."</h3>\n";
                    642:     $Str .= "<p>\n".&mt('LON-CAPA domain: [_1]',$domform)."\n</p>\n";
                    643:     $Str .= "<h3>".&mt('Starting and Ending Dates')."</h3>\n";
                    644:     $Str .= "<p>\n".$date_table."</p>\n";
                    645:     $Str .= "<h3>".&mt('Full Update')."</h3>\n";
1.131     albertel  646:     $Str .= '<label><input type="checkbox" name="fullup" value="yes">'.
1.90      matthew   647:         ' '.&mt('Full update (also print list of users not enrolled anymore)').
1.131     albertel  648:         "</label></p>\n";
1.90      matthew   649:     $Str .= "<h3>".&mt('Student Number')."</h3>\n";
1.131     albertel  650:     $Str .= "<p>\n".'<label><input type="checkbox" name="forceid" value="yes">';
1.90      matthew   651:     $Str .= &mt('Disable ID/Student Number Safeguard and Force Change '.
                    652:                 'of Conflicting IDs (only do if you know what you are doing)').
1.131     albertel  653:                 "</label>\n</p><p>\n";
1.142     raeburn   654:     $Str .= '<input type="button"'. 
                    655:               'onClick="javascript:verify(this.form,this.form.csec)" '.
1.95      albertel  656:         'value="Update Class List" />'."<br />\n";
1.90      matthew   657:     $Str .= &mt('Note: for large courses, this operation may be time '.
                    658:                 'consuming');
                    659:     $r->print($Str);
                    660:     return;
1.23      albertel  661: }
1.24      albertel  662: 
1.90      matthew   663: ###############################################################
                    664: ###############################################################
1.50      matthew   665: sub print_upload_manager_form {
1.23      albertel  666:     my $r=shift;
1.99      matthew   667: 
1.82      www       668:     my $firstLine;
1.24      albertel  669:     my $datatoken;
1.127     albertel  670:     if (!$env{'form.datatoken'}) {
1.90      matthew   671:         $datatoken=&Apache::loncommon::upfile_store($r);
1.24      albertel  672:     } else {
1.127     albertel  673:         $datatoken=$env{'form.datatoken'};
1.90      matthew   674:         &Apache::loncommon::load_tmp_file($r);
1.24      albertel  675:     }
                    676:     my @records=&Apache::loncommon::upfile_record_sep();
1.127     albertel  677:     if($env{'form.noFirstLine'}){
1.90      matthew   678:         $firstLine=shift(@records);
                    679:     }
1.23      albertel  680:     my $total=$#records;
                    681:     my $distotal=$total+1;
                    682:     my $today=time;
                    683:     my $halfyear=$today+15552000;
1.99      matthew   684:     #
                    685:     # Restore memorized settings
                    686:     &Apache::loncommon::restore_course_settings
                    687:         ('enrollment_upload',{ 'username_choice' => 'scalar', # column settings
                    688:                                'names_choice' => 'scalar',
                    689:                                'fname_choice' => 'scalar',
                    690:                                'mname_choice' => 'scalar',
                    691:                                'lname_choice' => 'scalar',
                    692:                                'gen_choice' => 'scalar',
                    693:                                'id_choice' => 'scalar',
                    694:                                'sec_choice' => 'scalar',
                    695:                                'ipwd_choice' => 'scalar',
                    696:                                'email_choice' => 'scalar',
                    697:                            });
                    698:     #
                    699:     # Determine kerberos parameters as appropriate
1.127     albertel  700:     my $defdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.64      albertel  701:     my ($krbdef,$krbdefdom) =
                    702:         &Apache::loncommon::get_kerberos_defaults($defdom);
1.99      matthew   703:     #
1.50      matthew   704:     &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom);
1.24      albertel  705:     my $i;
                    706:     my $keyfields;
1.23      albertel  707:     if ($total>=0) {
1.99      matthew   708:         my @field=
1.127     albertel  709:             (['username',&mt('Username'),     $env{'form.username_choice'}],
                    710:              ['names',&mt('Last Name, First Names'),$env{'form.names_choice'}],
                    711:              ['fname',&mt('First Name'),      $env{'form.fname_choice'}],
                    712:              ['mname',&mt('Middle Names/Initials'),$env{'form.mname_choice'}],
                    713:              ['lname',&mt('Last Name'),       $env{'form.lname_choice'}],
                    714:              ['gen',  &mt('Generation'),      $env{'form.gen_choice'}],
                    715:              ['id',   &mt('ID/Student Number'),$env{'form.id_choice'}],
1.142     raeburn   716:              ['sec',  &mt('Section'),          $env{'form.sec_choice'}],
1.127     albertel  717:              ['ipwd', &mt('Initial Password'),$env{'form.ipwd_choice'}],
                    718:              ['email',&mt('EMail Address'),   $env{'form.email_choice'}]);
                    719: 	if ($env{'form.upfile_associate'} eq 'reverse') {	
1.24      albertel  720: 	    &Apache::loncommon::csv_print_samples($r,\@records);
1.90      matthew   721: 	    $i=&Apache::loncommon::csv_print_select_table($r,\@records,
                    722:                                                           \@field);
                    723: 	    foreach (@field) { 
                    724:                 $keyfields.=$_->[0].','; 
                    725:             }
1.24      albertel  726: 	    chop($keyfields);
                    727: 	} else {
1.90      matthew   728: 	    unshift(@field,['none','']);
                    729: 	    $i=&Apache::loncommon::csv_samples_select_table($r,\@records,
                    730:                                                             \@field);
1.24      albertel  731: 	    my %sone=&Apache::loncommon::record_sep($records[0]);
                    732: 	    $keyfields=join(',',sort(keys(%sone)));
1.23      albertel  733: 	}
                    734:     }
1.50      matthew   735:     &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear);
1.10      www       736: }
                    737: 
1.90      matthew   738: ###############################################################
                    739: ###############################################################
1.12      www       740: sub enroll_single_student {
                    741:     my $r=shift;
1.80      matthew   742:     # Remove non alphanumeric values from section
1.127     albertel  743:     $env{'form.csec'}=~s/\W//g;
1.68      matthew   744:     #
                    745:     # We do the dates first because the action of making them the defaul
1.107     www       746:     # in the course is entirely separate from the action of enrolling the
1.68      matthew   747:     # student.  Also, a failure in setting the dates as default is not fatal
                    748:     # to the process of enrolling / modifying a student.
                    749:     my ($startdate,$enddate) = &get_dates_from_form();
1.127     albertel  750:     if ($env{'form.makedatesdefault'}) {
1.68      matthew   751:         $r->print(&make_dates_default($startdate,$enddate));
                    752:     }
                    753: 
1.94      sakharuk  754:     $r->print('<h3>'.&mt('Enrolling Student').'</h3>');
1.127     albertel  755:     $r->print('<p>'.&mt('Enrolling').' '.$env{'form.cuname'}." \@ ".
                    756:               $env{'form.lcdomain'}.'</p>');
1.150     albertel  757:     if (($env{'form.cuname'})
                    758: 	&& ($env{'form.cuname'} 
                    759: 	    eq &LONCAPA::clean_username($env{'form.cuname'}))
                    760: 	&& ($env{'form.lcdomain'})
                    761: 	&& ($env{'form.lcdomain'}
                    762: 	    eq &LONCAPA::clean_domain($env{'form.lcdomain'}))) {
1.31      matthew   763:         # Deal with home server selection
1.127     albertel  764:         my $domain=$env{'form.lcdomain'};
                    765:         my $desiredhost = $env{'form.lcserver'};
1.31      matthew   766:         if (lc($desiredhost) eq 'default') {
                    767:             $desiredhost = undef;
                    768:         } else {
1.157   ! albertel  769:             my %home_servers =&Apache::lonnet::get_servers($domain,'library');
1.31      matthew   770:             if (! exists($home_servers{$desiredhost})) {
1.94      sakharuk  771:                 $r->print('<font color="#ff0000">'.&mt('Error').':</font>'.
                    772:                           &mt('Invalid home server specified'));
1.31      matthew   773:                 return;
                    774:             }
                    775:         }
1.94      sakharuk  776:         $r->print(" ".&mt('with server')." $desiredhost :") if (defined($desiredhost));
1.31      matthew   777:         # End of home server selection logic
1.12      www       778: 	my $amode='';
                    779:         my $genpwd='';
1.127     albertel  780:         if ($env{'form.login'} eq 'krb') {
1.47      albertel  781:            $amode='krb';
1.127     albertel  782: 	   $amode.=$env{'form.krbver'};
                    783:            $genpwd=$env{'form.krbarg'};
                    784:         } elsif ($env{'form.login'} eq 'int') {
1.26      matthew   785:            $amode='internal';
1.127     albertel  786:            $genpwd=$env{'form.intarg'};
                    787:         }  elsif ($env{'form.login'} eq 'loc') {
1.15      albertel  788: 	    $amode='localauth';
1.127     albertel  789: 	    $genpwd=$env{'form.locarg'};
1.15      albertel  790: 	    if (!$genpwd) { $genpwd=" "; }
                    791: 	}
1.127     albertel  792:         my $home = &Apache::lonnet::homeserver($env{'form.cuname'},
                    793:                                                    $env{'form.lcdomain'});
1.34      matthew   794:         if ((($amode) && ($genpwd)) || ($home ne 'no_host')) {
1.55      matthew   795:             # Clean out any old roles the student has in this class.
1.127     albertel  796:             &modifystudent($env{'form.lcdomain'},$env{'form.cuname'},
                    797:                            $env{'request.course.id'},$env{'form.csec'},
1.33      matthew   798:                             $desiredhost);
1.55      matthew   799:             my $login_result = &Apache::lonnet::modifystudent
1.127     albertel  800:                 ($env{'form.lcdomain'},$env{'form.cuname'},
                    801:                  $env{'form.cstid'},$amode,$genpwd,
                    802:                  $env{'form.cfirst'},$env{'form.cmiddle'},
                    803:                  $env{'form.clast'},$env{'form.cgen'},
                    804:                  $env{'form.csec'},$enddate,
                    805:                  $startdate,$env{'form.forceid'},
                    806:                  $desiredhost,$env{'form.emailaddress'});
1.55      matthew   807:             if ($login_result =~ /^ok/) {
                    808:                 $r->print($login_result);
1.94      sakharuk  809:                 $r->print("<p> ".&mt('If active, the new role will be available when the student next logs in to LON-CAPA.')."</p>");
1.55      matthew   810:             } else {
1.94      sakharuk  811:                 $r->print(&mt('unable to enroll').": ".$login_result);
1.55      matthew   812:             }
1.12      www       813: 	} else {
1.94      sakharuk  814:             $r->print('<p><font color="#ff0000">'.&mt('ERROR').'</font>&nbsp;');
1.79      matthew   815:             if ($amode =~ /^krb/) {
1.94      sakharuk  816:                 $r->print(&mt('Missing Kerberos domain information.').'  ');
1.79      matthew   817:             } else {
1.94      sakharuk  818:                 $r->print(&mt('Invalid login mode or password.').'  ');
1.79      matthew   819:             }
1.127     albertel  820:             $r->print('<b>'.&mt('Unable to enroll').' '.$env{'form.cuname'}.'.</b></p>');
1.79      matthew   821:         }
1.12      www       822:     } else {
1.94      sakharuk  823:         $r->print(&mt('Invalid username or domain'));
1.26      matthew   824:     }    
1.155     www       825:     $r->print("<p><a href='/adm/dropadd?action=enrollstudent'>".&mt("Enroll another student")."</a></p>");
1.12      www       826: }
                    827: 
1.68      matthew   828: sub setup_date_selectors {
1.91      raeburn   829:     my ($starttime,$endtime,$mode) = @_;
1.68      matthew   830:     if (! defined($starttime)) {
                    831:         $starttime = time;
1.114     raeburn   832:         unless ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
1.127     albertel  833:             if (exists($env{'course.'.$env{'request.course.id'}.
1.68      matthew   834:                             '.default_enrollment_start_date'})) {
1.127     albertel  835:                 $starttime = $env{'course.'.$env{'request.course.id'}.
1.68      matthew   836:                                   '.default_enrollment_start_date'};
1.91      raeburn   837:             }
1.68      matthew   838:         }
                    839:     }
                    840:     if (! defined($endtime)) {
                    841:         $endtime = time+(6*30*24*60*60); # 6 months from now, approx
1.91      raeburn   842:         unless ($mode eq 'createcourse') {
1.127     albertel  843:             if (exists($env{'course.'.$env{'request.course.id'}.
1.68      matthew   844:                             '.default_enrollment_end_date'})) {
1.127     albertel  845:                 $endtime = $env{'course.'.$env{'request.course.id'}.
1.68      matthew   846:                                 '.default_enrollment_end_date'};
1.91      raeburn   847:             }
1.68      matthew   848:         }
                    849:     }
                    850:     my $startdateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    851:                                                             'startdate',
                    852:                                                             $starttime);
                    853:     my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    854:                                                           'enddate',
                    855:                                                           $endtime);
1.114     raeburn   856:     if ($mode eq 'create_enrolldates') {
                    857:         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    858:                                                             'startenroll',
                    859:                                                             $starttime);
                    860:         $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    861:                                                           'endenroll',
                    862:                                                           $endtime);
                    863:     }
                    864:     if ($mode eq 'create_defaultdates') {
1.91      raeburn   865:         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
1.114     raeburn   866:                                                             'startaccess',
1.91      raeburn   867:                                                             $starttime);
                    868:         $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
1.114     raeburn   869:                                                           'endaccess',
1.91      raeburn   870:                                                           $endtime);
                    871:     }
1.68      matthew   872:     return ($startdateform,$enddateform);
                    873: }
                    874: 
                    875: sub get_dates_from_form {
                    876:     my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
                    877:     my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate');
1.127     albertel  878:     if ($env{'form.no_end_date'}) {
1.68      matthew   879:         $enddate = 0;
                    880:     }
                    881:     return ($startdate,$enddate);
                    882: }
                    883: 
                    884: sub date_setting_table {
1.91      raeburn   885:     my ($starttime,$endtime,$mode) = @_;
                    886:     my ($startform,$endform)=&setup_date_selectors($starttime,$endtime,$mode);
1.68      matthew   887:     my $dateDefault = '<nobr>'.
1.131     albertel  888:         '<label><input type="checkbox" name="makedatesdefault" /> '.
                    889:         &mt('make these dates the default for future enrollment').'</label>';
1.114     raeburn   890:     if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
1.91      raeburn   891:         $dateDefault = '&nbsp;';
                    892:     }
1.131     albertel  893:     my $perpetual = '<nobr><label><input type="checkbox" name="no_end_date"';
1.68      matthew   894:     if (defined($endtime) && $endtime == 0) {
                    895:         $perpetual .= ' checked';
                    896:     }
1.131     albertel  897:     $perpetual.= ' /> '.&mt('no ending date').'</label></nobr>';
1.114     raeburn   898:     if ($mode eq 'create_enrolldates') {
                    899:         $perpetual = '&nbsp;';
                    900:     }
1.68      matthew   901:     my $result = '';
                    902:     $result .= "<table>\n";
1.94      sakharuk  903:     $result .= '<tr><td align="right">'.&mt('Starting Date').'</td>'.
1.68      matthew   904:         '<td>'.$startform.'</td>'.
                    905:         '<td>'.$dateDefault.'</td>'."</tr>\n";
1.94      sakharuk  906:     $result .= '<tr><td align="right">'.&mt('Ending Date').'</td>'.
1.68      matthew   907:         '<td>'.$endform.'</td>'.
                    908:         '<td>'.$perpetual.'</td>'."</tr>\n";
                    909:     $result .= "</table>\n";
                    910:     return $result;
                    911: }
                    912: 
                    913: sub make_dates_default {
                    914:     my ($startdate,$enddate) = @_;
                    915:     my $result = '';
1.127     albertel  916:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    917:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.68      matthew   918:     my $put_result = &Apache::lonnet::put('environment',
                    919:             {'default_enrollment_start_date'=>$startdate,
                    920:              'default_enrollment_end_date'  =>$enddate},$dom,$crs);
                    921:     if ($put_result eq 'ok') {
                    922:         $result .= "Set default start and end dates for course<br />";
1.69      matthew   923:         #
                    924:         # Refresh the course environment
1.140     albertel  925:         &Apache::lonnet::coursedescription($env{'request.course.id'},
                    926: 					   {'freshen_cache' => 1});
1.68      matthew   927:     } else {
1.94      sakharuk  928:         $result .= &mt('Unable to set default dates for course').":".$put_result.
1.68      matthew   929:             '<br />';
                    930:     }
                    931:     return $result;
                    932: }
                    933: 
1.74      matthew   934: ##
                    935: ## Single student enrollment routines (some of them)
                    936: ##
                    937: sub get_student_username_domain_form {
                    938:     my $r = shift;
                    939:     my $domform = &Apache::loncommon::select_dom_form
1.127     albertel  940:         ($env{'course.'.$env{'request.course.id'}.'.domain'},'cudomain',0);
1.94      sakharuk  941:     my %lt=&Apache::lonlocal::texthash(
                    942: 		    'eos'  => "Enroll One Student",
                    943: 		    'usr'  => "Username",
                    944:                     'dom'  => "Domain",
                    945:                     'been' => "Begin Enrollment",
                    946: 				       );
1.74      matthew   947:     $r->print(<<END);
                    948: <input type="hidden" name="action" value="enrollstudent" />
                    949: <input type="hidden" name="state"  value="gotusername" />
1.94      sakharuk  950: <h3>$lt{'eos'}</h3>
1.74      matthew   951: <table>
1.94      sakharuk  952: <tr><th>$lt{'usr'}:</th>
1.74      matthew   953:     <td><input type="text" name="cuname"  size="15" /></td></tr>
1.94      sakharuk  954: <tr><th>$lt{'dom'}:</th>
1.74      matthew   955:     <td>$domform</td></tr>
                    956: <tr><th>&nbsp;</th>
                    957:     <td>
1.94      sakharuk  958:     <input type="submit" name="Begin Enrollment" value="$lt{'been'}" />
1.74      matthew   959:     </td></tr>
                    960: </table>
1.120     albertel  961: <script type="text/javascript">
                    962: // the if prevents the script error if the browser can not handle this
                    963: if ( document.studentform.cuname ) { document.studentform.cuname.focus(); }
                    964: </script>
1.74      matthew   965: END
                    966:     return;
                    967: }
                    968: 
1.50      matthew   969: sub print_enroll_single_student_form {
1.10      www       970:     my $r=shift;
1.94      sakharuk  971:     $r->print("<h3>".&mt('Enroll One Student')."</h3>");
1.74      matthew   972:     #
1.150     albertel  973:     my $username = &LONCAPA::clean_username($env{'form.cuname'});
                    974:     my $domain   = &LONCAPA::clean_domain($env{'form.cudomain'});
1.74      matthew   975:     my $home = &Apache::lonnet::homeserver($username,$domain);
                    976:     # $new_user flags whether we are creating a new user or using an old one
                    977:     my $new_user = 1;
                    978:     if ($home ne 'no_host') {
                    979:         $new_user = 0;
                    980:     }
                    981:     #
                    982:     my $user_data_html = '';
                    983:     my $javascript_validations = '';
                    984:     if ($new_user) {
1.127     albertel  985:         my $defdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.74      matthew   986:         # Set up authentication forms
                    987:         my ($krbdef,$krbdefdom) =
1.75      matthew   988:             &Apache::loncommon::get_kerberos_defaults($domain);
1.89      matthew   989:         $javascript_validations=&javascript_validations('auth',$krbdefdom);
1.74      matthew   990:         my %param = ( formname => 'document.studentform',
                    991:                       kerb_def_dom => $krbdefdom,
                    992:                       kerb_def_auth => $krbdef
                    993:                       );
                    994:         my $krbform = &Apache::loncommon::authform_kerberos(%param);
                    995:         my $intform = &Apache::loncommon::authform_internal(%param);
                    996:         my $locform = &Apache::loncommon::authform_local(%param);
                    997:         #
                    998:         # Set up domain selection form
                    999:         my $homeserver_form = '';
1.157   ! albertel 1000:         my %servers = &Apache::lonnet::get_servers($domain,'library');
1.74      matthew  1001:         $homeserver_form = '<select name="lcserver" size="1">'."\n".
                   1002:             '<option value="default" selected>default</option>'."\n";
                   1003:         while (my ($servername,$serverdescription) = each (%servers)) {
                   1004:             $homeserver_form .= '<option value="'.$servername.'">'.
                   1005:                 $serverdescription."</option>\n";
                   1006:         }
                   1007:         $homeserver_form .= "</select>\n";
                   1008:         #
                   1009:         #
1.94      sakharuk 1010: 	my %lt=&Apache::lonlocal::texthash(
                   1011: 		       'udf'  => "User Data for",
                   1012:                        'fn'   => "First Name",
                   1013:                        'mn'   => "Middle Name",
                   1014:                        'ln'   => "Last Name",
                   1015:                        'gen'  => "Generation",
                   1016:                        'hs'   => "Home Server",
                   1017:                        'pswd' => "Password",
                   1018: 		       'psam' => "Please select an authentication mechanism",
1.124     www      1019:                        'mail' => "Email Address"
1.94      sakharuk 1020: 					   );
1.130     www      1021: 	my $authhelp=&Apache::loncommon::help_open_topic('Auth_Options');
1.74      matthew  1022:         $user_data_html = <<END;
1.94      sakharuk 1023: <h3>$lt{'udf'} $username\@$domain</h3>
1.74      matthew  1024: <table>
1.94      sakharuk 1025: <tr><th>$lt{'fn'}:</th>
1.74      matthew  1026:     <td><input type="text" name="cfirst"  size="15"></td></tr>
1.94      sakharuk 1027: <tr><th>$lt{'mn'}:</th>
1.74      matthew  1028:     <td><input type="text" name="cmiddle" size="15"></td></tr>
1.94      sakharuk 1029: <tr><th>$lt{'ln'}:</th>
1.74      matthew  1030:     <td><input type="text" name="clast"   size="15"></td></tr>
1.94      sakharuk 1031: <tr><th>$lt{'gen'}:</th>
1.74      matthew  1032:     <td><input type="text" name="cgen"    size="5"> </td></tr>
1.94      sakharuk 1033: <tr><th>$lt{'hs'}:</th>
1.74      matthew  1034:     <td>$homeserver_form</td></tr>
1.124     www      1035: <tr><th>$lt{'mail'}:</th>
                   1036:     <td><input type="text" name="emailaddress" size="20" /></td></tr>
1.74      matthew  1037: </table>
1.94      sakharuk 1038: <h3>$lt{'pswd'}</h3>
1.130     www      1039: $lt{'psam'}$authhelp
1.74      matthew  1040: <table>
                   1041: <p>
                   1042: $krbform
1.75      matthew  1043: <br />
1.74      matthew  1044: $intform
1.75      matthew  1045: <br />
1.74      matthew  1046: $locform
                   1047: </p>
                   1048: END
                   1049:     } else {
                   1050:         # User already exists.  Do not worry about authentication
                   1051:         my %uenv = &Apache::lonnet::dump('environment',$domain,$username);
1.89      matthew  1052:         $javascript_validations = &javascript_validations('noauth');
1.94      sakharuk 1053: 	my %lt=&Apache::lonlocal::texthash(
                   1054: 		       'udf'  => "User Data for",
                   1055:                        'fn'   => "First Name",
                   1056:                        'mn'   => "Middle Name",
                   1057:                        'ln'   => "Last Name",
                   1058:                        'gen'  => "Generation",
1.124     www      1059:                        'mail' => "Email Address",
1.94      sakharuk 1060: 					   );
1.74      matthew  1061:         $user_data_html = <<END;
1.94      sakharuk 1062: <h3>$lt{'udf'} $username\@$domain</h3>
1.74      matthew  1063: <input type="hidden" name="lcserver" value="default" />
                   1064: <table>
1.94      sakharuk 1065: <tr><th>$lt{'fn'}:</th>
1.74      matthew  1066:     <td>
                   1067:     <input type="text" name="cfirst" value="$uenv{'firstname'}" size="15" />
                   1068:     </td></tr>
1.94      sakharuk 1069: <tr><th>$lt{'mn'}:</th>
1.74      matthew  1070:     <td>
                   1071:     <input type="text" name="cmiddle" value="$uenv{'middlename'}" size="15" />
                   1072:     </td></tr>
1.94      sakharuk 1073: <tr><th>$lt{'ln'}:</th>
1.74      matthew  1074:     <td>
                   1075:     <input type="text" name="clast"value="$uenv{'lastname'}" size="15" />
                   1076:     </td></tr>
1.94      sakharuk 1077: <tr><th>$lt{'gen'}:</th>
1.74      matthew  1078:     <td>
                   1079:     <input type="text" name="cgen" value="$uenv{'generation'}" size="5" />
                   1080:     </td></tr>
1.124     www      1081: <tr><th>$lt{'mail'}:</th>
                   1082:     <td>
                   1083:     <input type="text" name="emailaddress" value="$uenv{'permanentemail'}" size="20" />
                   1084:     </td></tr>
1.74      matthew  1085: </table>
                   1086: END
                   1087:     }
1.68      matthew  1088:     my $date_table = &date_setting_table();
1.74      matthew  1089:         # Print it all out
1.94      sakharuk 1090:     my %lt=&Apache::lonlocal::texthash(
                   1091: 		   'cd'   => "Course Data",
1.142     raeburn  1092:                    'gs'   => "Section",
1.94      sakharuk 1093:                    'idsn' => "ID/Student Number",
                   1094:                    'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1095:                    'eas'  => "Enroll as student",
                   1096: 				       );
1.50      matthew  1097:     $r->print(<<END);
1.74      matthew  1098: <input type="hidden" name="action" value="enrollstudent" />
                   1099: <input type="hidden" name="state"  value="done" />
                   1100: <input type="hidden" name="cuname" value="$username" />
                   1101: <input type="hidden" name="lcdomain" value="$domain" />
1.28      matthew  1102: <script type="text/javascript" language="Javascript">
1.142     raeburn  1103: function verify(vf,sec_caller) {
1.12      www      1104:     var founduname=0;
                   1105:     var foundpwd=0;
                   1106:     var foundname=0;
                   1107:     var foundid=0;
                   1108:     var foundsec=0;
                   1109:     var tw;
1.26      matthew  1110:     if ((typeof(vf.cuname.value) !="undefined") && (vf.cuname.value!='') && 
1.31      matthew  1111: 	(typeof(vf.lcdomain.value)!="undefined") && (vf.lcdomain.value!='')) {
1.12      www      1112:         founduname=1;
                   1113:     }
1.14      harris41 1114:     if ((typeof(vf.cfirst.value)!="undefined") && (vf.cfirst.value!='') &&
1.26      matthew  1115: 	(typeof(vf.clast.value) !="undefined") && (vf.clast.value!='')) {
1.12      www      1116:         foundname=1;
                   1117:     }
1.14      harris41 1118:     if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) {
1.12      www      1119:         foundsec=1;
1.142     raeburn  1120:         if (validate(sec_caller) == "error") {
                   1121:             return;
                   1122:         }
1.12      www      1123:     }
1.14      harris41 1124:     if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) {
1.12      www      1125: 	foundid=1;
                   1126:     }
                   1127:     if (founduname==0) {
                   1128: 	alert('You need to specify at least the username and domain fields');
                   1129:         return;
                   1130:     }
1.24      albertel 1131:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
1.12      www      1132: }
                   1133: 
1.24      albertel 1134: $javascript_validations
1.12      www      1135: 
1.24      albertel 1136: function clearpwd(vf) {
                   1137:     //nothing else needs clearing
1.15      albertel 1138: }
                   1139: 
1.12      www      1140: </script>
1.11      www      1141: 
1.74      matthew  1142: $user_data_html
1.50      matthew  1143: 
1.94      sakharuk 1144: <h3>$lt{'cd'}</h3>
1.50      matthew  1145: 
1.94      sakharuk 1146: <p>$lt{'gs'}: <input type="text" name="csec" size="5" />
1.50      matthew  1147: <p>
1.68      matthew  1148: $date_table
1.50      matthew  1149: </p>
1.94      sakharuk 1150: <h3>$lt{'idsn'}</h3>
1.50      matthew  1151: <p>
1.94      sakharuk 1152: $lt{'idsn'}: <input type="text" name="cstid" size="10">
1.26      matthew  1153: </p><p>
1.131     albertel 1154: <label>
1.26      matthew  1155: <input type="checkbox" name="forceid" value="yes"> 
1.94      sakharuk 1156: $lt{'disn'}
1.131     albertel 1157: </label>
1.50      matthew  1158: </p><p>
1.142     raeburn  1159: <input type="button" onClick="verify(this.form,this.form.csec)" value="$lt{'eas'}">
1.26      matthew  1160: </p>
1.50      matthew  1161: END
                   1162:     return;
1.10      www      1163: }
                   1164: 
                   1165: # ========================================================= Menu Phase Two Drop
1.51      matthew  1166: sub print_drop_menu {
1.10      www      1167:     my $r=shift;
1.92      sakharuk 1168:     $r->print("<h3>".&mt('Drop Students')."</h3>");
1.127     albertel 1169:     my $cid=$env{'request.course.id'};
1.56      matthew  1170:     my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
                   1171:     if (! defined($classlist)) {
1.94      sakharuk 1172:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.51      matthew  1173:         return;
1.25      matthew  1174:     }
1.51      matthew  1175:     # Print out the available choices
1.56      matthew  1176:     &show_drop_list($r,$classlist,$keylist);
1.51      matthew  1177:     return;
1.11      www      1178: }
                   1179: 
1.40      matthew  1180: # ============================================== view classlist
1.50      matthew  1181: sub print_html_classlist {
1.103     matthew  1182:     my ($r,$mode) = @_;
1.127     albertel 1183:     if (! exists($env{'form.sortby'})) {
                   1184:         $env{'form.sortby'} = 'username';
1.57      matthew  1185:     }
1.147     albertel 1186:     if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.127     albertel 1187:         $env{'form.Status'} = 'Active';
1.57      matthew  1188:     }
                   1189:     my $status_select = &Apache::lonhtmlcommon::StatusOptions
1.127     albertel 1190:         ($env{'form.Status'});
1.150     albertel 1191:     my $cid =$env{'request.course.id'};
1.127     albertel 1192:     my $cdom=$env{'course.'.$cid.'.domain'};
                   1193:     my $cnum=$env{'course.'.$cid.'.num'};
1.103     matthew  1194:     #
                   1195:     # List course personnel
1.100     www      1196:     my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);
1.110     matthew  1197:     #
1.127     albertel 1198:     if (! defined($env{'form.output'}) ||
                   1199:         $env{'form.output'} !~ /^(csv|excel|html)$/ ) {
                   1200:         $env{'form.output'} = 'html';
1.110     matthew  1201:     }
                   1202:     #
1.139     albertel 1203:     $r->print('<br />'.&Apache::loncommon::start_data_table());
1.110     matthew  1204:     foreach my $role (sort keys %coursepersonnel) {
                   1205:         next if ($role =~ /^\s*$/);
1.139     albertel 1206: 	$r->print(&Apache::loncommon::start_data_table_row().
                   1207: 		  '<td>'.$role.'</td><td>');
1.110     matthew  1208:         foreach my $user (split(',',$coursepersonnel{$role})) {
                   1209: 	    my ($puname,$pudom)=split(':',$user);
1.100     www      1210: 	    $r->print(' '.&Apache::loncommon::aboutmewrapper(
1.110     matthew  1211:                                     &Apache::loncommon::plainname($puname,
                   1212:                                                                   $pudom),
                   1213:                                                              $puname,$pudom));
1.100     www      1214: 	}
1.139     albertel 1215:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.100     www      1216:     }
1.139     albertel 1217:     $r->print(&Apache::loncommon::end_data_table());
1.103     matthew  1218:     #
                   1219:     # Interface output
                   1220:     $r->print('<input type="hidden" name="action" value="'.
1.127     albertel 1221:               $env{'form.action'}.'" />');
1.103     matthew  1222:     $r->print("<p>\n");
1.127     albertel 1223:     if ($env{'form.action'} ne 'modifystudent') {
1.103     matthew  1224: 	my %lt=&Apache::lonlocal::texthash('csv' => "CSV",
                   1225:                                            'excel' => "Excel",
                   1226:                                            'html'  => 'HTML');
1.110     matthew  1227:         my $output_selector = '<select size="1" name="output" >';
1.103     matthew  1228:         foreach my $outputformat ('html','csv','excel') {
                   1229:             my $option = '<option value="'.$outputformat.'" ';
1.127     albertel 1230:             if ($outputformat eq $env{'form.output'}) {
1.104     matthew  1231:                 $option .= 'selected ';
1.103     matthew  1232:             }
                   1233:             $option .='>'.$lt{$outputformat}.'</option>';
                   1234:             $output_selector .= "\n".$option;
                   1235:         }
                   1236:         $output_selector .= '</select>';
                   1237:         $r->print(&mt('Output Format: [_1]',$output_selector).('&nbsp;'x3));
1.59      matthew  1238:     }
1.103     matthew  1239:     $r->print(&mt('Student Status: [_1]',$status_select)."\n");
1.105     matthew  1240:     $r->print('<input type="submit" value="'.&mt('Update Display').'" />'.
                   1241:               "\n</p>\n");
1.103     matthew  1242:     #
                   1243:     # Print the classlist
                   1244:     $r->print('<h2>'.&mt('Current Class List').'</h2>');
1.56      matthew  1245:     my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   1246:     if (! defined($classlist)) {
1.94      sakharuk 1247:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.40      matthew  1248:     } else {
                   1249:         # Print out the available choices
1.127     albertel 1250:         if ($env{'form.action'} eq 'modifystudent') {
1.110     matthew  1251:             &show_class_list($r,'view','modify',
1.127     albertel 1252:                              $env{'form.Status'},$classlist,$keylist);
1.110     matthew  1253:         } else {
1.127     albertel 1254:             &show_class_list($r,$env{'form.output'},'aboutme',
                   1255:                              $env{'form.Status'},$classlist,$keylist);
1.50      matthew  1256:         }
1.41      matthew  1257:     }
                   1258: }
                   1259: 
1.40      matthew  1260: # =================================================== Show student list to drop
                   1261: sub show_class_list {
1.110     matthew  1262:     my ($r,$mode,$linkto,$statusmode,$classlist,$keylist)=@_;
1.127     albertel 1263:     my $cid=$env{'request.course.id'};
1.142     raeburn  1264:     my $cdom = $env{'course.'.$cid.'.domain'};
                   1265:     my $cnum = $env{'course.'.$cid.'.num'};
                   1266:     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
                   1267:                                               $classlist,$keylist,$cdom,$cnum);
1.60      matthew  1268:     #
                   1269:     # Variables for excel output
1.104     matthew  1270:     my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);
1.60      matthew  1271:     #
1.103     matthew  1272:     # Variables for csv output
                   1273:     my ($CSVfile,$CSVfilename);
                   1274:     #
1.127     albertel 1275:     my $sortby = $env{'form.sortby'};
1.142     raeburn  1276:     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end|type)$/) {
1.53      matthew  1277:         $sortby = 'username';
                   1278:     }
1.134     raeburn  1279:     if (! exists($env{'form.displayphotos'})) {
                   1280:         $env{'form.displayphotos'} = 'off';
                   1281:     }
                   1282:     my $displayphotos = $env{'form.displayphotos'};
                   1283: 
1.42      matthew  1284:     # Print out header 
1.114     raeburn  1285:     unless ($mode eq 'autoenroll') {
                   1286:         $r->print(<<END);
1.127     albertel 1287: <input type="hidden" name="state" value="$env{'form.state'}" />
1.114     raeburn  1288: END
                   1289:     }
1.103     matthew  1290:     $r->print(<<END);
                   1291: <input type="hidden" name="sortby" value="$sortby" />
1.134     raeburn  1292: <input type="hidden" name="displayphotos" value="$displayphotos" />
1.103     matthew  1293: END
1.114     raeburn  1294:     if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') {
1.50      matthew  1295:         if ($linkto eq 'aboutme') {
1.142     raeburn  1296:             $r->print(&mt("Select a user name to view the user's personal page."));
1.50      matthew  1297:         } elsif ($linkto eq 'modify') {
1.142     raeburn  1298:             $r->print(&mt("Select a user name to modify the student's information"));
1.50      matthew  1299:         }
1.94      sakharuk 1300: 	my %lt=&Apache::lonlocal::texthash(
1.110     matthew  1301:                                            'usrn'   => "username",
                   1302:                                            'dom'    => "domain",
                   1303:                                            'sn'     => "student name",
                   1304:                                            'sec'    => "section",
1.142     raeburn  1305:                                            'grp'    => "active groups",
1.110     matthew  1306:                                            'start'  => "start date",
                   1307:                                            'end'    => "end date",
1.134     raeburn  1308:                                            'type'   => "enroll type/action",
                   1309:                                            'photo'  => "photo",
1.94      sakharuk 1310: 					   );
1.114     raeburn  1311:         unless ($mode eq 'autoenroll') {
                   1312:             $r->print(<<END);
1.59      matthew  1313: <input type="hidden" name="sname"  value="" />
                   1314: <input type="hidden" name="sdom"   value="" />
1.114     raeburn  1315: END
                   1316:         }
1.136     raeburn  1317:         if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
1.134     raeburn  1318:             $r->print('
                   1319: <script type="text/javascript">
                   1320: function photowindow(photolink) {
                   1321:     var title = "Photo_Viewer";
                   1322:     var options = "scrollbars=1,resizable=1,menubar=0";
                   1323:     options += ",width=240,height=240";
                   1324:     stdeditbrowser = open(photolink,title,options,"1");
                   1325:     stdeditbrowser.focus();
                   1326: }
                   1327: </script>
                   1328:            ');
                   1329:         }
1.115     raeburn  1330:         $r->print("
1.40      matthew  1331: <p>
1.139     albertel 1332: ".&Apache::loncommon::start_data_table()."
1.115     raeburn  1333: <tr>
                   1334:         ");
                   1335:         if ($mode eq 'autoenroll') {
                   1336:             $r->print("
                   1337:  <th><a href=\"javascript:document.studentform.sortby.value='type';document.studentform.submit();\">$lt{'type'}</a></th>
                   1338:             ");
                   1339:         } else {
                   1340:             $r->print("
                   1341: <th>Count</th>
                   1342:             ");
                   1343:         }
                   1344:         $r->print(<<END);
                   1345:     <th>
1.94      sakharuk 1346:        <a href="javascript:document.studentform.sortby.value='username';document.studentform.submit();">$lt{'usrn'}</a>
1.53      matthew  1347:     </th><th>
1.94      sakharuk 1348:        <a href="javascript:document.studentform.sortby.value='domain';document.studentform.submit();">$lt{'dom'}</a>
1.53      matthew  1349:     </th><th>
1.57      matthew  1350:        <a href="javascript:document.studentform.sortby.value='id';document.studentform.submit();">ID</a>
1.53      matthew  1351:     </th><th>
1.94      sakharuk 1352:        <a href="javascript:document.studentform.sortby.value='fullname';document.studentform.submit();">$lt{'sn'}</a>
1.53      matthew  1353:     </th><th>
1.94      sakharuk 1354:        <a href="javascript:document.studentform.sortby.value='section';document.studentform.submit();">$lt{'sec'}</a>
1.110     matthew  1355:     </th><th>
                   1356:        <a href="javascript:document.studentform.sortby.value='start';document.studentform.submit();">$lt{'start'}</a>
                   1357:     </th><th>
                   1358:        <a href="javascript:document.studentform.sortby.value='end';document.studentform.submit();">$lt{'end'}</a>
1.142     raeburn  1359:     </th><th>
                   1360:        <a href="javascript:document.studentform.sortby.value='groups';document.studentform.submit();">$lt{'grp'}</a>
1.53      matthew  1361:     </th>
1.40      matthew  1362: END
1.136     raeburn  1363:         if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
1.135     albertel 1364:             my %photo_options = &Apache::lonlocal::texthash(
1.134     raeburn  1365:                                                             'on' => 'Show',
                   1366:                                                             'off' => 'Hide',
                   1367:                                                             );
                   1368:             my $photochg = 'on';
                   1369:             if ($displayphotos eq 'on') {
                   1370:                 $photochg = 'off';
                   1371:             }
                   1372:             $r->print('    <th>'."\n".'     '. 
                   1373:             '<a href="javascript:document.studentform.displayphotos.value='.
                   1374:                       "'".$photochg."'".';document.studentform.submit();">'.
                   1375:                       $photo_options{$photochg}.'</a>&nbsp;'.$lt{'photo'}."\n".
                   1376:                       '    </th>'."\n");
                   1377:         }
                   1378:         $r->print("  </tr>\n");
1.41      matthew  1379:     } elsif ($mode eq 'csv') {
1.103     matthew  1380: 	#
                   1381: 	# Open a file
                   1382: 	$CSVfilename = '/prtspool/'.
1.127     albertel 1383: 	    $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
1.103     matthew  1384:             time.'_'.rand(1000000000).'.csv';
                   1385: 	unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {
                   1386: 	    $r->log_error("Couldn't open $CSVfilename for output $!");
                   1387: 	    $r->print("Problems occured in writing the csv file.  ".
                   1388: 		      "This error has been logged.  ".
                   1389: 		      "Please alert your LON-CAPA administrator.");
                   1390: 	    $CSVfile = undef;
                   1391: 	}
                   1392: 	#
                   1393: 	# Write headers and data to file
1.58      matthew  1394:         if($statusmode eq 'Expired') {
1.103     matthew  1395:             print $CSVfile '"'.&mt('Students with expired roles').'"'."\n";
1.58      matthew  1396:         }
1.147     albertel 1397:         if($statusmode eq 'Future') {
                   1398:             print $CSVfile '"'.&mt('Students with future roles').'"'."\n";
                   1399:         }
1.58      matthew  1400:         if ($statusmode eq 'Any') {
1.103     matthew  1401:             print $CSVfile '"'.join('","',map {
                   1402: 		&Apache::loncommon::csv_translate(&mt($_))
                   1403:                 } ("username","domain","ID","student name",
1.142     raeburn  1404:                    "section","start date","end date","status","active groups"))
                   1405:                   .'"'."\n";
1.58      matthew  1406:         } else {
1.103     matthew  1407:             print $CSVfile '"'.join('","',map {
                   1408: 		&Apache::loncommon::csv_translate(&mt($_))
                   1409:                 } ("username","domain","ID","student name",
1.142     raeburn  1410:                    "section","start date","end date","active groups")).'"'."\n";
1.58      matthew  1411:         }
1.60      matthew  1412:     } elsif ($mode eq 'excel') {
                   1413:         # Create the excel spreadsheet
1.126     matthew  1414:         ($excel_workbook,$excel_filename,$format) = 
                   1415:             &Apache::loncommon::create_workbook($r);
                   1416:         return if (! defined($excel_workbook));
1.60      matthew  1417:         $excel_sheet = $excel_workbook->addworksheet('classlist');
                   1418:         #
1.76      albertel 1419:         my $description = 'Class List for '.
1.127     albertel 1420:             $env{'course.'.$env{'request.course.id'}.'.description'};
1.104     matthew  1421:         $excel_sheet->write($row++,0,$description,$format->{'h1'});
1.60      matthew  1422:         #
                   1423:         $excel_sheet->write($row++,0,["username","domain","ID",
1.110     matthew  1424:                                       "student name","section",
1.142     raeburn  1425:                                       "start date","end date","status",
                   1426:                                       "active groups"],
1.110     matthew  1427:                             $format->{'bold'});
1.41      matthew  1428:     }
1.56      matthew  1429:     #
                   1430:     # Sort the students
                   1431:     my %index;
                   1432:     my $i;
                   1433:     foreach (@$keylist) {
                   1434:         $index{$_} = $i++;
                   1435:     }
1.142     raeburn  1436:     $index{'groups'} = scalar(@{$keylist});
1.56      matthew  1437:     my $index  = $index{$sortby};
                   1438:     my $second = $index{'username'};
                   1439:     my $third  = $index{'domain'};
1.53      matthew  1440:     my @Sorted_Students = sort {
1.56      matthew  1441:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   1442:             ||
                   1443:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   1444:             ||
                   1445:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   1446:         } (keys(%$classlist));
1.108     matthew  1447:     my $studentcount = 0;
1.115     raeburn  1448:     my $autocount = 0;
                   1449:     my $manualcount = 0;
                   1450:     my $unlockcount = 0;
                   1451:     my $lockcount = 0;
1.53      matthew  1452:     foreach my $student (@Sorted_Students) {
1.110     matthew  1453:         my $sdata = $classlist->{$student};
1.142     raeburn  1454:         my $groups = $classgroups->{$student};
1.110     matthew  1455:         my $username = $sdata->[$index{'username'}];
                   1456:         my $domain   = $sdata->[$index{'domain'}];
                   1457:         my $section  = $sdata->[$index{'section'}];
1.142     raeburn  1458:         my $active_groups;
                   1459:         if (ref($groups->{active}) eq 'HASH') {
                   1460:             $active_groups = join(', ',keys(%{$groups->{'active'}}));
                   1461:         }
1.110     matthew  1462:         my $name     = $sdata->[$index{'fullname'}];
                   1463:         my $id       = $sdata->[$index{'id'}];
                   1464:         my $status   = $sdata->[$index{'status'}];
                   1465:         my $start    = $sdata->[$index{'start'}];
                   1466:         my $end      = $sdata->[$index{'end'}];
1.115     raeburn  1467:         my $type     = $sdata->[$index{'type'}];
1.57      matthew  1468:         next if (($statusmode ne 'Any') && ($status ne $statusmode));
1.114     raeburn  1469:         if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
                   1470:             if (! defined($start) || $start == 0) {
                   1471:                 $start = &mt('none');
                   1472:             } else {
                   1473:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1474:             }
                   1475:             if (! defined($end) || $end == 0) {
                   1476:                 $end = &mt('none');
                   1477:             } else {
                   1478:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1479:             }
1.139     albertel 1480: 	    $r->print(&Apache::loncommon::start_data_table_row());
1.115     raeburn  1481:             if ($mode eq 'autoenroll') {
                   1482:                 my $lockedtype = $sdata->[$index{'lockedtype'}];
                   1483:                 $studentcount++;
                   1484:                 my $cellentry;
                   1485:                 if ($type eq 'auto') {
1.131     albertel 1486:                     $cellentry = '<b>'.&mt('auto').'</b>&nbsp;<label><input type="checkbox" name="chgauto" value="'.$username.':'.$domain.'" />&nbsp;Change</label>';
1.115     raeburn  1487:                     $autocount ++;
                   1488:                 } else {
1.131     albertel 1489:                     $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.'" />&nbsp;Change</label></nobr></td></tr><tr><td><nobr>';
1.115     raeburn  1490:                     $manualcount ++;
                   1491:                     if ($lockedtype) {
1.131     albertel 1492:                         $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Unlock').'</label>';
1.115     raeburn  1493:                         $unlockcount ++;
                   1494:                     } else {
1.131     albertel 1495:                         $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Lock').'</label>';
1.115     raeburn  1496:                         $lockcount ++;
                   1497:                     }
1.118     raeburn  1498:                     $cellentry .= '</nobr></td></tr></table>';
1.115     raeburn  1499:                 }
                   1500:                 $r->print("<td>$cellentry<td>\n    ");
                   1501:             } else {
                   1502:                 $r->print("<td>".(++$studentcount)."</td><td>\n    ");
                   1503:             }
1.51      matthew  1504:             if ($linkto eq 'nothing') {
                   1505:                 $r->print($username);
                   1506:             } elsif ($linkto eq 'aboutme') {
                   1507:                 $r->print(&Apache::loncommon::aboutmewrapper($username,
                   1508:                                                              $username,
                   1509:                                                              $domain));
                   1510:             } elsif ($linkto eq 'modify') {
1.59      matthew  1511:                 $r->print('<a href="'.
                   1512:                           "javascript:document.studentform.sname.value='".
                   1513:                           $username.
                   1514:                           "';document.studentform.sdom.value='".$domain.
                   1515:                           "';document.studentform.state.value='selected".
                   1516:                           "';document.studentform.submit();".'">'.
1.53      matthew  1517:                           $username."</a>\n");
1.50      matthew  1518:             }
1.51      matthew  1519:             $r->print(<<"END");
1.50      matthew  1520:     </td>
1.51      matthew  1521:     <td>$domain</td>
                   1522:     <td>$id</td>
                   1523:     <td>$name</td>
                   1524:     <td>$section</td>
1.110     matthew  1525:     <td>$start</td>
                   1526:     <td>$end</td>
1.142     raeburn  1527:     <td>$active_groups</td>
1.114     raeburn  1528: END
1.134     raeburn  1529:             if ($env{'course.'.$env{'request.course.id'}.
1.136     raeburn  1530: 			 '.internal.showphoto'}) {
1.134     raeburn  1531:                 if ($displayphotos eq 'on') {
1.135     albertel 1532:                     my $imgurl = 
                   1533: 			&Apache::lonnet::retrievestudentphoto($domain,
                   1534: 							      $username,'gif',
                   1535: 							      'thumbnail');
1.134     raeburn  1536:                 
                   1537:                     $r->print('    <td align="right"><a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($domain,$username,'jpg')."'".')"><img src="'.$imgurl.'" border="1"></a></td>');
                   1538:                 } else {
                   1539:                     $r->print('    <td>&nbsp;</td>  ');
                   1540:                 }
                   1541:             }
1.139     albertel 1542: 	    $r->print(&Apache::loncommon::end_data_table_row());
1.51      matthew  1543:         } elsif ($mode eq 'csv') {
1.103     matthew  1544:             next if (! defined($CSVfile));
1.51      matthew  1545:             # no need to bother with $linkto
1.114     raeburn  1546:             if (! defined($start) || $start == 0) {
                   1547:                 $start = &mt('none');
                   1548:             } else {
                   1549:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1550:             }
                   1551:             if (! defined($end) || $end == 0) {
                   1552:                 $end = &mt('none');
                   1553:             } else {
                   1554:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1555:             }
1.51      matthew  1556:             my @line = ();
1.110     matthew  1557:             foreach ($username,$domain,$id,$name,$section,$start,$end) {
1.51      matthew  1558:                 push @line,&Apache::loncommon::csv_translate($_);
1.58      matthew  1559:             }
                   1560:             if ($statusmode eq 'Any') {
                   1561:                 push @line,&Apache::loncommon::csv_translate($status);
1.41      matthew  1562:             }
1.142     raeburn  1563:             push @line,&Apache::loncommon::csv_translate($active_groups);
1.103     matthew  1564:             print $CSVfile '"'.join('","',@line).'"'."\n";
1.60      matthew  1565:         } elsif ($mode eq 'excel') {
1.110     matthew  1566:             $excel_sheet->write($row,0,[$username,$domain,$id,
                   1567:                                           $name,$section]);
                   1568:             my $col = 5;
                   1569:             foreach my $time ($start,$end) {
1.129     matthew  1570:                 if (defined($time) && $time != 0) {
                   1571:                     $excel_sheet->write($row,$col++,
1.110     matthew  1572:                                    &Apache::lonstathelpers::calc_serial($time),
                   1573:                                     $format->{'date'});
1.129     matthew  1574:                 } else {
                   1575:                     $excel_sheet->write($row,$col++,'none');
                   1576:                 }                    
1.110     matthew  1577:             }
                   1578:             $excel_sheet->write($row,$col++,$status);
1.142     raeburn  1579:             $excel_sheet->write($row,$col++,$active_groups);
1.110     matthew  1580:             $row++;
1.40      matthew  1581:         }
                   1582:     }
1.114     raeburn  1583:     if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
1.139     albertel 1584: 	$r->print(&Apache::loncommon::end_data_table().'<br />');
1.60      matthew  1585:     } elsif ($mode eq 'excel') {
                   1586:         $excel_workbook->close();
                   1587:         $r->print('<p><a href="'.$excel_filename.'">'.
1.94      sakharuk 1588:                   &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
1.103     matthew  1589:     } elsif ($mode eq 'csv') {
                   1590:         close($CSVfile);
                   1591:         $r->print('<a href="'.$CSVfilename.'">'.
                   1592:                   &mt('Your CSV file').'</a> is ready for download.'.
                   1593:                   "\n");
                   1594:         $r->rflush();
1.60      matthew  1595:     }
1.114     raeburn  1596:     if ($mode eq 'autoenroll') {
1.115     raeburn  1597:         return ($studentcount,$autocount,$manualcount,$lockcount,$unlockcount);
1.114     raeburn  1598:     }
1.115     raeburn  1599:     return;
1.40      matthew  1600: }
                   1601: 
1.50      matthew  1602: 
                   1603: #
                   1604: # print out form for modification of a single students data
                   1605: #
                   1606: sub print_modify_student_form {
                   1607:     my $r = shift();
                   1608:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.59      matthew  1609:                                             ['sdom','sname']);    
1.127     albertel 1610:     my $sname  = $env{'form.sname'};
                   1611:     my $sdom   = $env{'form.sdom'};
                   1612:     my $sortby = $env{'form.sortby'};
1.50      matthew  1613:     # determine the students name information
                   1614:     my %info=&Apache::lonnet::get('environment',
                   1615:                                   ['firstname','middlename',
1.52      matthew  1616:                                    'lastname','generation','id'],
1.50      matthew  1617:                                   $sdom, $sname);
                   1618:     my ($tmp) = keys(%info);
                   1619:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1620:         $r->print('<font color="#ff0000" size="+2">'.&mt('Error').'</font>'.
1.50      matthew  1621:                   '<p>'.
1.94      sakharuk 1622:                   &mt('Unable to retrieve environment data for').' '.$sname.
                   1623:                   &mt('in domain').' '.$sdom.'</p><p>'.
1.138     albertel 1624:                   &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p>'.&Apache::loncommon::end_page());
1.50      matthew  1625:         return;
                   1626:     }
                   1627:     # determine the students starting and ending times and section
                   1628:     my ($starttime,$endtime,$section) = &get_enrollment_data($sname,$sdom);
1.87      matthew  1629:     if ($starttime =~ /^error/) {
1.94      sakharuk 1630:         $r->print('<h2>'&mt('Error').'</h2>');
1.87      matthew  1631:         $r->print('<p>'.$starttime.'</p>');
                   1632:         return;
                   1633:     }
1.101     matthew  1634:     #
1.50      matthew  1635:     # Deal with date forms
1.101     matthew  1636:     my $current_date_description = '';
                   1637:     my $textdate = '';
                   1638: 
                   1639:     if (! defined($starttime) || $starttime == 0) {
                   1640:         $current_date_description = &mt('Current Starting Date: not set').
                   1641:             '<br />';
                   1642:     } else {
                   1643:         $current_date_description = 
                   1644:             &mt('Current Starting Date: [_1]',
                   1645:                 &Apache::lonlocal::locallocaltime($starttime)).'<br />';
                   1646:     }
                   1647:     if (! defined($endtime) || $endtime == 0) {
                   1648:         $current_date_description.= &mt('Current Ending Date: not set').
                   1649:             '<br />';
                   1650:     } else {
                   1651:         $current_date_description.= 
                   1652:             &mt('Current Ending Date: [_1]',
                   1653:                 &Apache::lonlocal::locallocaltime($endtime)).'<br />';
                   1654: 
                   1655:     }
1.68      matthew  1656:     my $date_table = &date_setting_table($starttime,$endtime);
1.59      matthew  1657:     #
1.127     albertel 1658:     if (! exists($env{'form.Status'}) || 
1.147     albertel 1659:         $env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.127     albertel 1660:         $env{'form.Status'} = 'crap';
1.59      matthew  1661:     }
1.94      sakharuk 1662:     # Make sure student is enrolled in course
                   1663:     my %lt=&Apache::lonlocal::texthash(
                   1664: 	           'mef'   => "Modify Enrollment for",
                   1665:                    'odcc'  => "Only domain coordinators can change a users password.",
                   1666:                    'sn'    => "Student Name",
                   1667:                    'fn'    => "First",
                   1668:                    'mn'    => "Middle",
                   1669:                    'ln'    => "Last",
                   1670:                    'gen'   => "Generation",
                   1671:                    'sid'   => "Student ID",
                   1672:                    'disn'  => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1673:                    'sec'   => "Section",
                   1674:                    'sm'    => "Submit Modifications",
                   1675: 				       );
1.142     raeburn  1676: # Check if section name is valid
                   1677:     my $section_check = &section_check_js();
                   1678:     $r->print(<<"END");
                   1679: <script type="text/javascript">
                   1680: $section_check
                   1681: function secverify(formname,caller) {
                   1682:     if (validate(caller) == "error") {
                   1683:         return;
                   1684:     } else {
                   1685:         formname.submit();
                   1686:     }
                   1687: }
                   1688: </script>
1.52      matthew  1689: <p>
                   1690: <font size="+1">
1.94      sakharuk 1691: $lt{'odcc'}
1.52      matthew  1692: </font>
                   1693: </p>
1.50      matthew  1694: <input type="hidden" name="slogin"  value="$sname"  />
                   1695: <input type="hidden" name="sdomain" value="$sdom" />
                   1696: <input type="hidden" name="action"  value="modifystudent" />
1.53      matthew  1697: <input type="hidden" name="state"   value="done" />
                   1698: <input type="hidden" name="sortby"  value="$sortby" />
1.127     albertel 1699: <input type="hidden" name="Status"  value="$env{'form.Status'}" />
1.94      sakharuk 1700: <h2>$lt{'mef'} $info{'firstname'} $info{'middlename'} 
1.50      matthew  1701: $info{'lastname'} $info{'generation'}, $sname\@$sdom</h2>
                   1702: <p>
1.94      sakharuk 1703: <b>$lt{'sn'}</b>
1.50      matthew  1704: <table>
1.94      sakharuk 1705: <tr><th>$lt{'fn'}</th><th>$lt{'mn'}</th><th>$lt{'ln'}</th><th>$lt{'gen'}</th></tr>
1.50      matthew  1706: <tr><td>
                   1707: <input type="text" name="firstname"  value="$info{'firstname'}"  /></td><td>
                   1708: <input type="text" name="middlename" value="$info{'middlename'}" /></td><td>
                   1709: <input type="text" name="lastname"   value="$info{'lastname'}"   /></td><td>
                   1710: <input type="text" name="generation" value="$info{'generation'}" /></td></tr>
                   1711: </table>
                   1712: </p><p>
1.94      sakharuk 1713: <b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12"/>
1.52      matthew  1714: </p><p>
1.131     albertel 1715: <label>
1.53      matthew  1716: <input type="checkbox" name="forceid" > 
1.94      sakharuk 1717: $lt{'disn'}
1.131     albertel 1718: </label>
1.53      matthew  1719: </p><p>
1.101     matthew  1720: <b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="14"/>
1.50      matthew  1721: </p>
1.101     matthew  1722: <p>$current_date_description</p>
1.68      matthew  1723: <p>$date_table</p>
1.142     raeburn  1724: <input type="button" value="$lt{'sm'}" onClick="secverify(this.form,this.form.section)" />
1.50      matthew  1725: END
1.138     albertel 1726:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  1727:     return;
                   1728: }
                   1729: 
                   1730: #
                   1731: # modify a single students section 
                   1732: #
                   1733: sub modify_single_student {
1.138     albertel 1734:     my ($r) = @_;
1.68      matthew  1735:     #
1.80      matthew  1736:     # Remove non alphanumeric values from the section
1.127     albertel 1737:     $env{'form.section'} =~ s/\W//g;
1.77      matthew  1738:     #
1.68      matthew  1739:     # Do the date defaults first
                   1740:     my ($starttime,$endtime) = &get_dates_from_form();
1.127     albertel 1741:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  1742:         $r->print(&make_dates_default($starttime,$endtime));
                   1743:     }
1.59      matthew  1744:     # Get the 'sortby' and 'Status' variables so the user goes back to their
                   1745:     # previous screen
1.127     albertel 1746:     my $sortby = $env{'form.sortby'};
                   1747:     my $status = $env{'form.Status'};
1.53      matthew  1748:     #
                   1749:     # We always need this information
1.127     albertel 1750:     my $slogin     = $env{'form.slogin'};
                   1751:     my $sdom       = $env{'form.sdomain'};
1.53      matthew  1752:     #
                   1753:     # Get the old data
                   1754:     my %old=&Apache::lonnet::get('environment',
                   1755:                                  ['firstname','middlename',
                   1756:                                   'lastname','generation','id'],
                   1757:                                  $sdom, $slogin);
1.59      matthew  1758:     $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin,
1.127     albertel 1759:                                                   $env{'request.course.id'});
1.53      matthew  1760:     my ($tmp) = keys(%old);
                   1761:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1762:         $r->print(&mt('There was an error determining the environment values for')." $slogin \@ $sdom.");
1.53      matthew  1763:         return;
                   1764:     }
                   1765:     undef $tmp;
                   1766:     #
                   1767:     # Get the new data
1.127     albertel 1768:     my $firstname  = $env{'form.firstname'};
                   1769:     my $middlename = $env{'form.middlename'};
                   1770:     my $lastname   = $env{'form.lastname'};
                   1771:     my $generation = $env{'form.generation'};
                   1772:     my $section    = $env{'form.section'};
                   1773:     my $courseid   = $env{'request.course.id'};
                   1774:     my $sid        = $env{'form.id'};
1.50      matthew  1775:     my $displayable_starttime = localtime($starttime);
                   1776:     my $displayable_endtime   = localtime($endtime);
1.53      matthew  1777:     # 
                   1778:     # check for forceid override
1.63      matthew  1779:     if ((defined($old{'id'})) && ($old{'id'} ne '') && 
1.127     albertel 1780:         ($sid ne $old{'id'}) && (! exists($env{'form.forceid'}))) {
1.94      sakharuk 1781:         $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>");
1.53      matthew  1782:         $sid = $old{'id'};
                   1783:     }
                   1784:     #
1.50      matthew  1785:     # talk to the user about what we are going to do
1.94      sakharuk 1786:     my %lt=&Apache::lonlocal::texthash(
                   1787: 	           'mdu'   => "Modifying data for user",
                   1788:                    'si'    => "Student Information",
                   1789:                    'fd'    => "Field",
                   1790:                    'ov'    => "Old Value",
                   1791:                    'nv'    => "New Value",
                   1792:                    'fn'    => "First name",
                   1793:                    'mn'    => "Middle name",
                   1794:                    'ln'    => "Last name",
                   1795:                    'gen'   => "Generation",
                   1796:                    'sec'   => "Section",
                   1797:                    'ri'    => "Role Information",
                   1798:                    'st'    => "Start Time",
                   1799:                    'et'    => "End Time",
                   1800: 				       );
1.50      matthew  1801:     $r->print(<<END);
1.94      sakharuk 1802:     <h2>$lt{'mdu'} $slogin \@ $sdom </h2>
                   1803: <h3>$lt{'si'}</h3>
1.53      matthew  1804: <table rules="rows" border="1" cellpadding="3" >
                   1805: <tr>
1.94      sakharuk 1806:     <th> $lt{'fd'} </th>
                   1807:     <th> $lt{'ov'} </th>
                   1808:     <th> $lt{'nv'} </th>
1.53      matthew  1809: </tr>
                   1810: <tr>
1.94      sakharuk 1811:     <td> <b>$lt{'fn'}</b> </td>
1.53      matthew  1812:     <td> $old{'firstname'} </td>
                   1813:     <td> $firstname </td>
                   1814: </tr><tr>
1.94      sakharuk 1815:     <td> <b>$lt{'mn'}</b> </td>
1.53      matthew  1816:     <td> $old{'middlename'} </td>
                   1817:     <td> $middlename </td>
                   1818: </tr><tr>
1.94      sakharuk 1819:     <td> <b>$lt{'ln'}</b> </td>
1.53      matthew  1820:     <td> $old{'lastname'} </td>
                   1821:     <td> $lastname </td>
                   1822: </tr><tr>
1.94      sakharuk 1823:     <td> <b>$lt{'gen'}</b> </td>
1.53      matthew  1824:     <td> $old{'generation'} </td>
                   1825:     <td> $generation </td>
                   1826: </tr><tr>
                   1827:     <td> <b>ID</b> </td>
                   1828:     <td> $old{'id'} </td>
                   1829:     <td> $sid </td>
1.59      matthew  1830: </tr><tr>
1.94      sakharuk 1831:     <td> <b>$lt{'sec'}</b> </td>
1.59      matthew  1832:     <td> $old{'section'} </td>
                   1833:     <td> $section</td>
1.53      matthew  1834: </tr>
1.50      matthew  1835: </table>
1.94      sakharuk 1836: <h3>$lt{'ri'}</h3>
1.50      matthew  1837: <table>
1.94      sakharuk 1838: <tr><td align="right"><b>$lt{'st'}:</b></td><td> $displayable_starttime </td></tr>
                   1839: <tr><td align="right"><b>$lt{'et'}:</b></td><td> $displayable_endtime   </td></tr>
1.50      matthew  1840: </table>
1.52      matthew  1841: <p>
1.50      matthew  1842: END
1.53      matthew  1843:     #
1.63      matthew  1844:     # Send request(s) to modify data (final undef is for 'desiredhost',
                   1845:     # which is a moot point because the student already has an account.
                   1846:     my $modify_section_results = &modifystudent($sdom,$slogin,
1.127     albertel 1847:                                                 $env{'request.course.id'},
1.63      matthew  1848:                                                 $section,undef);
                   1849:     if ($modify_section_results !~ /^ok/) {
1.94      sakharuk 1850:         $r->print(&mt('An error occured during the attempt to change the section for this student.')."<br />");
1.63      matthew  1851:     }
1.52      matthew  1852:     my $roleresults = &Apache::lonnet::modifystudent
1.53      matthew  1853:         ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname,
1.127     albertel 1854:          $generation,$section,$endtime,$starttime,$env{'form.forceid'});
1.53      matthew  1855:     if ($roleresults eq 'refused' ) {
1.94      sakharuk 1856:         $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.'));
1.50      matthew  1857:     } elsif ($roleresults !~ /ok/) {
1.94      sakharuk 1858:         $r->print(&mt('An error occurred during the attempt to change the role information for this student.')."  <br />".
                   1859:                   &mt('The error reported was')." ".
1.50      matthew  1860:                   $roleresults);
1.53      matthew  1861:         &Apache::lonnet::logthis("londropadd:failed attempt to modify student".
                   1862:                                  " data for ".$slogin." \@ ".$sdom." by ".
1.127     albertel 1863:                                  $env{'user.name'}." \@ ".$env{'user.domain'}.
1.53      matthew  1864:                                  ":".$roleresults);
1.50      matthew  1865:     } else { # everything is okay!
1.94      sakharuk 1866:         $r->print(&mt('Student information updated successfully.')." <br />".
                   1867:                   &mt('The student must log out and log in again to see these changes.'));
1.50      matthew  1868:     }
1.94      sakharuk 1869:     my $Masd=&mt('Modify another students data');
1.50      matthew  1870:     $r->print(<<END);
1.52      matthew  1871: </p><p>
1.59      matthew  1872: <input type="hidden" name="action" value="modifystudent" />
                   1873: <input type="hidden" name="sortby" value="$sortby" />
                   1874: <input type="hidden" name="Status" value="$status" />
1.94      sakharuk 1875: <a href="javascript:document.studentform.submit();">$Masd</a>
1.50      matthew  1876: END
1.138     albertel 1877:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  1878:     return;
                   1879: }
                   1880: 
                   1881: sub get_enrollment_data {
                   1882:     my ($sname,$sdomain) = @_;
1.127     albertel 1883:     my $courseid = $env{'request.course.id'};
1.151     albertel 1884:     my $cdom = $env{'course.'.$courseid.'.domain'};
                   1885:     my $cnum = $env{'course.'.$courseid.'.num'};
1.50      matthew  1886:     my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname);
                   1887:     my ($tmp) = keys(%roles);
                   1888:     # Bail out if we were unable to get the students roles
1.87      matthew  1889:     return ('error'.$tmp) if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.50      matthew  1890:     # Go through the roles looking for enrollment in this course
                   1891:     my ($end,$start) = (undef,undef);
                   1892:     my $section = '';
                   1893:     my $count = scalar(keys(%roles));
                   1894:     while (my ($course,$role) = each(%roles)) {
1.150     albertel 1895:         if ($course=~m{^/\Q$cdom\E/\Q$cnum\E/*\s*(\w+)*_st$} ) {
1.50      matthew  1896:             #
                   1897:             # Get active role
                   1898:             $section=$1;
                   1899:             (undef,$end,$start)=split(/\_/,$role);
                   1900:             my $now=time;
                   1901:             my $notactive=0;
                   1902:             if ($start) {
                   1903:                 if ($now<$start) { $notactive=1; }
                   1904:             }
                   1905:             if ($end) {
                   1906:                 if ($now>$end) { $notactive=1; }
                   1907:             } 
                   1908:             unless ($notactive) { return ($start,$end,$section); }
                   1909:         }
                   1910:     }
                   1911:     return ($start,$end,$section);
                   1912: }
                   1913: 
1.56      matthew  1914: #################################################
                   1915: #################################################
                   1916: 
                   1917: =pod
                   1918: 
                   1919: =item show_drop_list
                   1920: 
                   1921: Display a list of students to drop
                   1922: Inputs: 
                   1923: 
                   1924: =over 4
                   1925: 
                   1926: =item $r, Apache request
                   1927: 
                   1928: =item $classlist, hash pointer returned from loncoursedata::get_classlist();
                   1929: 
                   1930: =item $keylist, array pointer returned from loncoursedata::get_classlist() 
                   1931: which describes the order elements are stored in the %$classlist values.
                   1932: 
                   1933: =item $nosort, if true, sorting links are omitted.
                   1934: 
                   1935: =back
                   1936: 
                   1937: =cut
                   1938: 
                   1939: #################################################
                   1940: #################################################
1.11      www      1941: sub show_drop_list {
1.56      matthew  1942:     my ($r,$classlist,$keylist,$nosort)=@_;
1.127     albertel 1943:     my $cid=$env{'request.course.id'};
                   1944:     if (! exists($env{'form.sortby'})) {
1.59      matthew  1945:         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   1946:                                                 ['sortby']);
                   1947:     }
1.127     albertel 1948:     my $sortby = $env{'form.sortby'};
1.142     raeburn  1949:     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) {
1.54      matthew  1950:         $sortby = 'username';
                   1951:     }
1.142     raeburn  1952:     my $cdom = $env{'course.'.$cid.'.domain'};
                   1953:     my $cnum = $env{'course.'.$cid,'.num'};
                   1954:     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
1.143     raeburn  1955:                                               $classlist,$keylist,$cdom,$cnum);
1.56      matthew  1956:     #
1.54      matthew  1957:     my $action = "drop";
                   1958:     $r->print(<<END);
                   1959: <input type="hidden" name="sortby" value="$sortby" />
                   1960: <input type="hidden" name="action" value="$action" />
1.50      matthew  1961: <input type="hidden" name="state"  value="done" />
1.32      matthew  1962: <script>
1.51      matthew  1963: function checkAll(field) {
1.32      matthew  1964:     for (i = 0; i < field.length; i++)
                   1965:         field[i].checked = true ;
                   1966: }
                   1967: 
1.51      matthew  1968: function uncheckAll(field) {
1.32      matthew  1969:     for (i = 0; i < field.length; i++)
                   1970:         field[i].checked = false ;
                   1971: }
                   1972: </script>
                   1973: <p>
1.26      matthew  1974: <input type="hidden" name="phase" value="four">
1.56      matthew  1975: END
                   1976: 
1.110     matthew  1977: my %lt=&Apache::lonlocal::texthash('usrn'   => "username",
                   1978:                                    'dom'    => "domain",
                   1979:                                    'sn'     => "student name",
                   1980:                                    'sec'    => "section",
                   1981:                                    'start'  => "start date",
                   1982:                                    'end'    => "end date",
1.142     raeburn  1983:                                    'groups' => "active groups",
1.110     matthew  1984:                                    );
1.56      matthew  1985:     if ($nosort) {
1.139     albertel 1986: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  1987:         $r->print(<<END);
                   1988: <tr>
                   1989:     <th>&nbsp;</th>
1.94      sakharuk 1990:     <th>$lt{'usrn'}</th>
                   1991:     <th>$lt{'dom'}</th>
1.56      matthew  1992:     <th>ID</th>
1.94      sakharuk 1993:     <th>$lt{'sn'}</th>
                   1994:     <th>$lt{'sec'}</th>
1.110     matthew  1995:     <th>$lt{'start'}</th>
                   1996:     <th>$lt{'end'}</th>
1.142     raeburn  1997:     <th>$lt{'groups'}</th>
1.56      matthew  1998: </tr>
                   1999: END
                   2000: 
                   2001:     } else  {
1.139     albertel 2002: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  2003:         $r->print(<<END);
1.54      matthew  2004: <tr><th>&nbsp;</th>
                   2005:     <th>
1.94      sakharuk 2006:        <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a>
1.54      matthew  2007:     </th><th>
1.94      sakharuk 2008:        <a href="/adm/dropadd?action=$action&sortby=domain">$lt{'dom'}</a>
1.54      matthew  2009:     </th><th>
                   2010:        <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
                   2011:     </th><th>
1.94      sakharuk 2012:        <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a>
1.54      matthew  2013:     </th><th>
1.94      sakharuk 2014:        <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a>
1.110     matthew  2015:     </th><th>
                   2016:        <a href="/adm/dropadd?action=$action&sortby=start">$lt{'start'}</a>
                   2017:     </th><th>
                   2018:        <a href="/adm/dropadd?action=$action&sortby=end">$lt{'end'}</a>
1.142     raeburn  2019:     </th><th>
                   2020:        <a href="/adm/dropadd?action=$action&sortby=groups">$lt{'groups'}</a>
1.54      matthew  2021:     </th>
                   2022: </tr>
1.26      matthew  2023: END
1.56      matthew  2024:     }
                   2025:     #
                   2026:     # Sort the students
                   2027:     my %index;
                   2028:     my $i;
                   2029:     foreach (@$keylist) {
                   2030:         $index{$_} = $i++;
                   2031:     }
1.142     raeburn  2032:     $index{'groups'} = scalar(@$keylist);
1.56      matthew  2033:     my $index  = $index{$sortby};
                   2034:     my $second = $index{'username'};
                   2035:     my $third  = $index{'domain'};
1.54      matthew  2036:     my @Sorted_Students = sort {
1.56      matthew  2037:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   2038:             ||
                   2039:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   2040:             ||
                   2041:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   2042:         } (keys(%$classlist));
1.54      matthew  2043:     foreach my $student (@Sorted_Students) {
1.52      matthew  2044:         my $error;
1.110     matthew  2045:         my $sdata = $classlist->{$student};
                   2046:         my $username = $sdata->[$index{'username'}];
                   2047:         my $domain   = $sdata->[$index{'domain'}];
                   2048:         my $section  = $sdata->[$index{'section'}];
                   2049:         my $name     = $sdata->[$index{'fullname'}];
                   2050:         my $id       = $sdata->[$index{'id'}];
                   2051:         my $start    = $sdata->[$index{'start'}];
                   2052:         my $end      = $sdata->[$index{'end'}];
1.142     raeburn  2053:         my $groups = $classgroups->{$student};
                   2054:         my $active_groups;
                   2055:         if (ref($groups->{active}) eq 'HASH') {
                   2056:             $active_groups = join(', ',keys(%{$groups->{'active'}}));
                   2057:         }
1.110     matthew  2058:         if (! defined($start) || $start == 0) {
                   2059:             $start = &mt('none');
                   2060:         } else {
                   2061:             $start = &Apache::lonlocal::locallocaltime($start);
                   2062:         }
                   2063:         if (! defined($end) || $end == 0) {
                   2064:             $end = &mt('none');
                   2065:         } else {
                   2066:             $end = &Apache::lonlocal::locallocaltime($end);
                   2067:         }
                   2068:         my $status   = $sdata->[$index{'status'}];
1.51      matthew  2069:         next if ($status ne 'Active');
                   2070:         #
1.139     albertel 2071:         $r->print(&Apache::loncommon::start_data_table_row());
1.51      matthew  2072:         $r->print(<<"END");
                   2073:     <td><input type="checkbox" name="droplist" value="$student"></td>
                   2074:     <td>$username</td>
                   2075:     <td>$domain</td>
                   2076:     <td>$id</td>
                   2077:     <td>$name</td>
                   2078:     <td>$section</td>
1.110     matthew  2079:     <td>$start</td>
                   2080:     <td>$end</td>
1.142     raeburn  2081:     <td>$active_groups</td>
1.26      matthew  2082: END
1.139     albertel 2083:         $r->print(&Apache::loncommon::end_data_table_row());
1.25      matthew  2084:     }
1.139     albertel 2085:     $r->print(&Apache::loncommon::end_data_table().'<br />');
1.111     matthew  2086:     %lt=&Apache::lonlocal::texthash(
1.94      sakharuk 2087: 	               'dp'   => "Drop Students",
                   2088:                        'ca'   => "check all",
                   2089:                        'ua'   => "uncheck all",
                   2090: 				       );
1.32      matthew  2091:     $r->print(<<"END");
                   2092: </p><p>
1.94      sakharuk 2093: <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)"> &nbsp;
                   2094: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)"> 
                   2095: <p><input type=submit value="$lt{'dp'}"></p>
1.32      matthew  2096: END
1.51      matthew  2097:     return;
1.10      www      2098: }
                   2099: 
1.48      matthew  2100: #
                   2101: # Print out the initial form to get the courselist file
                   2102: #
                   2103: sub print_first_courselist_upload_form {
                   2104:     my $r=shift;
1.88      matthew  2105:     my $str;
                   2106:     $str  = '<input type="hidden" name="phase" value="two">';
                   2107:     $str .= '<input type="hidden" name="action" value="upload" />';
                   2108:     $str .= '<input type="hidden"   name="state"  value="got_file" />';
                   2109:     $str .= "<h3>".&mt('Upload a class list')."</h3>\n";
                   2110:     $str .= &Apache::loncommon::upfile_select_html();
                   2111:     $str .= "<p>\n";
                   2112:     $str .= '<input type="submit" name="fileupload" value="'.
                   2113:         &mt('Upload class list').'">'."\n";
1.131     albertel 2114:     $str .= '<label><input type="checkbox" name="noFirstLine" /> '.
                   2115:         &mt('Ignore First Line')."</label></p>\n";
1.88      matthew  2116:     $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
1.92      sakharuk 2117:                          &mt("How do I create a class list from a spreadsheet")).
1.88      matthew  2118:                              "<br />\n";
                   2119:     $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
1.92      sakharuk 2120:                            &mt("How do I create a CSV file from a spreadsheet")).
1.88      matthew  2121:                                "<br />\n";
1.138     albertel 2122:     $str .= &Apache::loncommon::end_page();
1.88      matthew  2123:     $r->print($str);
1.48      matthew  2124:     return;
                   2125: }
                   2126: 
1.10      www      2127: # ================================================= Drop/Add from uploaded file
                   2128: sub upfile_drop_add {
                   2129:     my $r=shift;
1.24      albertel 2130:     &Apache::loncommon::load_tmp_file($r);
                   2131:     my @studentdata=&Apache::loncommon::upfile_record_sep();
1.127     albertel 2132:     if($env{'form.noFirstLine'}){shift(@studentdata);}
                   2133:     my @keyfields = split(/\,/,$env{'form.keyfields'});
                   2134:     my $cid = $env{'request.course.id'};
1.25      matthew  2135:     my %fields=();
1.127     albertel 2136:     for (my $i=0; $i<=$env{'form.nfields'}; $i++) {
                   2137:         if ($env{'form.upfile_associate'} eq 'reverse') {
                   2138:             if ($env{'form.f'.$i} ne 'none') {
                   2139:                 $fields{$keyfields[$i]}=$env{'form.f'.$i};
1.25      matthew  2140:             }
                   2141:         } else {
1.127     albertel 2142:             $fields{$env{'form.f'.$i}}=$keyfields[$i];
1.25      matthew  2143:         }
                   2144:     }
1.99      matthew  2145:     #
                   2146:     # Store the field choices away
                   2147:     foreach my $field (qw/username names 
                   2148:                        fname mname lname gen id sec ipwd email/) {
1.127     albertel 2149:         $env{'form.'.$field.'_choice'}=$fields{$field};
1.99      matthew  2150:     }
                   2151:     &Apache::loncommon::store_course_settings('enrollment_upload',
                   2152:                                               { 'username_choice' => 'scalar',
                   2153:                                                 'names_choice' => 'scalar',
                   2154:                                                 'fname_choice' => 'scalar',
                   2155:                                                 'mname_choice' => 'scalar',
                   2156:                                                 'lname_choice' => 'scalar',
                   2157:                                                 'gen_choice' => 'scalar',
                   2158:                                                 'id_choice' => 'scalar',
                   2159:                                                 'sec_choice' => 'scalar',
                   2160:                                                 'ipwd_choice' => 'scalar',
                   2161:                                                 'email_choice' => 'scalar' });
                   2162: 
1.26      matthew  2163:     #
1.68      matthew  2164:     my ($startdate,$enddate) = &get_dates_from_form();
1.127     albertel 2165:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  2166:         $r->print(&make_dates_default($startdate,$enddate));
                   2167:     }
1.31      matthew  2168:     # Determine domain and desired host (home server)
1.127     albertel 2169:     my $domain=$env{'form.lcdomain'};
                   2170:     my $desiredhost = $env{'form.lcserver'};
1.31      matthew  2171:     if (lc($desiredhost) eq 'default') {
                   2172:         $desiredhost = undef;
                   2173:     } else {
1.157   ! albertel 2174:         my %home_servers = &Apache::lonnet::get_servers($domain,'library');
1.31      matthew  2175:         if (! exists($home_servers{$desiredhost})) {
1.88      matthew  2176:             $r->print('<font color="#ff0000">'.&mt('Error').'</font>'.
                   2177:                       &mt('Invalid home server specified'));
1.138     albertel 2178:             $r->print(&Apache::loncommon::end_page());
1.31      matthew  2179:             return;
                   2180:         }
                   2181:     }
1.26      matthew  2182:     # Determine authentication mechanism
                   2183:     my $amode  = '';
                   2184:     my $genpwd = '';
1.127     albertel 2185:     if ($env{'form.login'} eq 'krb') {
1.47      albertel 2186:         $amode='krb';
1.127     albertel 2187: 	$amode.=$env{'form.krbver'};
                   2188:         $genpwd=$env{'form.krbarg'};
                   2189:     } elsif ($env{'form.login'} eq 'int') {
1.25      matthew  2190:         $amode='internal';
1.127     albertel 2191:         if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
                   2192:             $genpwd=$env{'form.intarg'};
1.25      matthew  2193:         }
1.127     albertel 2194:     } elsif ($env{'form.login'} eq 'loc') {
1.25      matthew  2195:         $amode='localauth';
1.127     albertel 2196:         if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {
                   2197:             $genpwd=$env{'form.locarg'};
1.79      matthew  2198:         }
                   2199:     }
                   2200:     if ($amode =~ /^krb/) {
                   2201:         if (! defined($genpwd) || $genpwd eq '') {
                   2202:             $r->print('<font color="red" size="+1">'.
1.88      matthew  2203:                       &mt('Unable to enroll students').'</font>  '.
                   2204:                       &mt('No Kerberos domain was specified.').'</p>');
1.79      matthew  2205:             $amode = ''; # This causes the loop below to be skipped
1.25      matthew  2206:         }
                   2207:     }
1.154     raeburn  2208:     if ( $domain eq &LONCAPA::clean_domain($domain)
1.150     albertel 2209: 	&& ($amode ne '')) {
1.26      matthew  2210:         #######################################
                   2211:         ##         Enroll Students           ##
                   2212:         #######################################
1.88      matthew  2213:         $r->print('<h3>'.&mt('Enrolling Students')."</h3>\n<p>\n");
1.25      matthew  2214:         my $count=0;
                   2215:         my $flushc=0;
                   2216:         my %student=();
1.142     raeburn  2217:         # Get information about course groups
1.143     raeburn  2218:         my %curr_groups = &Apache::longroup::coursegroups();
1.26      matthew  2219:         # Get new classlist
1.25      matthew  2220:         foreach (@studentdata) {
                   2221:             my %entries=&Apache::loncommon::record_sep($_);
1.26      matthew  2222:             # Determine student name
1.25      matthew  2223:             unless (($entries{$fields{'username'}} eq '') ||
                   2224:                     (!defined($entries{$fields{'username'}}))) {
1.26      matthew  2225:                 my ($fname, $mname, $lname,$gen) = ('','','','');
1.25      matthew  2226:                 if (defined($fields{'names'})) {
1.26      matthew  2227:                     ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
                   2228:                                             /([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.25      matthew  2229:                 } else {
                   2230:                     if (defined($fields{'fname'})) {
                   2231:                         $fname=$entries{$fields{'fname'}};
                   2232:                     }
                   2233:                     if (defined($fields{'mname'})) {
                   2234:                         $mname=$entries{$fields{'mname'}};
                   2235:                     }
                   2236:                     if (defined($fields{'lname'})) {
                   2237:                         $lname=$entries{$fields{'lname'}};
                   2238:                     }
                   2239:                     if (defined($fields{'gen'})) {
                   2240:                         $gen=$entries{$fields{'gen'}};
                   2241:                     }
                   2242:                 }
1.150     albertel 2243:                 if ($entries{$fields{'username'}}
                   2244: 		    ne &LONCAPA::clean_username($entries{$fields{'username'}})) {
1.88      matthew  2245:                     $r->print('<br />'.
                   2246:       &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
                   2247:           $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
                   2248:                               '</b>');
1.25      matthew  2249:                 } else {
1.26      matthew  2250:                     # determine section number
1.25      matthew  2251:                     my $sec='';
                   2252:                     my $username=$entries{$fields{'username'}};
                   2253:                     if (defined($fields{'sec'})) {
                   2254:                         if (defined($entries{$fields{'sec'}})) {
                   2255:                             $sec=$entries{$fields{'sec'}};
                   2256:                         }
                   2257:                     }
1.80      matthew  2258:                     # remove non alphanumeric values from section
                   2259:                     $sec =~ s/\W//g;
1.142     raeburn  2260:                     if ($sec eq "none" || $sec eq 'all') {
                   2261:                         $r->print('<br />'.
                   2262:       &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a reserved word.',
                   2263:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2264:                         next;
                   2265:                     } elsif (($sec ne '') && (exists($curr_groups{$sec}))) {
                   2266:                         $r->print('<br />'.
                   2267:       &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.',
                   2268:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2269:                         next;
                   2270:                     }
1.26      matthew  2271:                     # determine student id number
1.25      matthew  2272:                     my $id='';
                   2273:                     if (defined($fields{'id'})) {
                   2274:                         if (defined($entries{$fields{'id'}})) {
                   2275:                             $id=$entries{$fields{'id'}};
                   2276:                         }
                   2277:                         $id=~tr/A-Z/a-z/;
                   2278:                     }
1.73      www      2279:                     # determine email address
                   2280:                     my $email='';
                   2281:                     if (defined($fields{'email'})) {
                   2282:                         if (defined($entries{$fields{'email'}})) {
                   2283:                             $email=$entries{$fields{'email'}};
                   2284:                             unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
                   2285:                         }
                   2286:                     }
1.26      matthew  2287:                     # determine student password
1.25      matthew  2288:                     my $password='';
                   2289:                     if ($genpwd) { 
                   2290:                         $password=$genpwd; 
                   2291:                     } else {
                   2292:                         if (defined($fields{'ipwd'})) {
                   2293:                             if ($entries{$fields{'ipwd'}}) {
                   2294:                                 $password=$entries{$fields{'ipwd'}};
                   2295:                             }
                   2296:                         }
                   2297:                     }
1.56      matthew  2298:                     # Clean up whitespace
                   2299:                     foreach (\$domain,\$username,\$id,\$fname,\$mname,
                   2300:                              \$lname,\$gen,\$sec) {
                   2301:                         $$_ =~ s/(\s+$|^\s+)//g;
                   2302:                     }
1.127     albertel 2303:                     if ($password || $env{'form.login'} eq 'loc') {
1.33      matthew  2304:                         &modifystudent($domain,$username,$cid,$sec,
                   2305:                                        $desiredhost);
1.25      matthew  2306:                         my $reply=&Apache::lonnet::modifystudent
                   2307:                             ($domain,$username,$id,$amode,$password,
                   2308:                              $fname,$mname,$lname,$gen,$sec,$enddate,
1.127     albertel 2309:                              $startdate,$env{'form.forceid'},$desiredhost,
1.73      www      2310:                              $email);
1.26      matthew  2311:                         if ($reply ne 'ok') {
1.72      matthew  2312:                             $reply =~ s/^error://;
1.88      matthew  2313:                             $r->print('<br />'.
                   2314:                 &mt('<b>[_1]</b>:  Unable to enroll: [_2]',$username,$reply));
1.10      www      2315:          		} else {
1.7       www      2316:                             $count++; $flushc++;
                   2317:                             $student{$username}=1;
1.6       www      2318:                             $r->print('. ');
1.7       www      2319:                             if ($flushc>15) {
                   2320: 				$r->rflush;
                   2321:                                 $flushc=0;
                   2322:                             }
1.6       www      2323:                         }
1.25      matthew  2324:                     } else {
1.88      matthew  2325:                         $r->print('<br />'.
                   2326:       &mt('<b>[_1]</b>: Unable to enroll.  No password specified.',$username)
                   2327:                                   );
1.25      matthew  2328:                     }
                   2329:                 }
1.26      matthew  2330:             }
                   2331:         } # end of foreach (@studentdata)
1.88      matthew  2332:         $r->print("</p>\n<p>\n".&mt('Processed [_1] student(s).',$count).
                   2333:                   "</p>\n");
                   2334:         $r->print("<p>\n".
                   2335:                   &mt('If active, the new role will be available when the '.
                   2336:                   'students next log in to LON-CAPA.')."</p>\n");
1.26      matthew  2337:         #####################################
                   2338:         #           Drop students           #
                   2339:         #####################################
1.127     albertel 2340:         if ($env{'form.fullup'} eq 'yes') {
1.88      matthew  2341:             $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");
1.26      matthew  2342:             #  Get current classlist
1.56      matthew  2343:             my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   2344:             if (! defined($classlist)) {
1.88      matthew  2345:                 $r->print(&mt('There are no students currently enrolled.').
                   2346:                           "\n");
1.56      matthew  2347:             } else {
                   2348:                 # Remove the students we just added from the list of students.
1.25      matthew  2349:                 foreach (@studentdata) {
                   2350:                     my %entries=&Apache::loncommon::record_sep($_);
                   2351:                     unless (($entries{$fields{'username'}} eq '') ||
                   2352:                             (!defined($entries{$fields{'username'}}))) {
1.56      matthew  2353:                         delete($classlist->{$entries{$fields{'username'}}.
1.26      matthew  2354:                                                 ':'.$domain});
1.25      matthew  2355:                     }
                   2356:                 }
1.56      matthew  2357:                 # Print out list of dropped students.
                   2358:                 &show_drop_list($r,$classlist,$keylist,'nosort');
1.25      matthew  2359:             }
                   2360:         }
1.26      matthew  2361:     } # end of unless
1.10      www      2362: }
                   2363: 
1.11      www      2364: # ================================================================== Phase four
                   2365: sub drop_student_list {
                   2366:     my $r=shift;
                   2367:     my $count=0;
1.128     albertel 2368:     my @droplist = &Apache::loncommon::get_env_multiple('form.droplist');
1.35      matthew  2369:     foreach (@droplist) {
1.26      matthew  2370:         my ($uname,$udom)=split(/\:/,$_);
1.56      matthew  2371:         # drop student
1.127     albertel 2372:         my $result = &modifystudent($udom,$uname,$env{'request.course.id'});
1.37      matthew  2373:         if ($result eq 'ok' || $result eq 'ok:') {
1.88      matthew  2374:             $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>');
1.59      matthew  2375:             $count++;
1.35      matthew  2376:         } else {
1.88      matthew  2377:             $r->print(
                   2378:           &mt('Error dropping [_1]:[_2]',$uname.'@'.$udom,$result).
1.35      matthew  2379:                       '<br />');
                   2380:         }
1.20      harris41 2381:     }
1.88      matthew  2382:     $r->print('<p><b>'.&mt('Dropped [_1] student(s).',$count).'</b></p>');
                   2383:     $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count);
1.11      www      2384: }
                   2385: 
1.142     raeburn  2386: sub section_check_js {
                   2387:     my $groupslist;
1.143     raeburn  2388:     my %curr_groups = &Apache::longroup::coursegroups();
1.142     raeburn  2389:     if (%curr_groups) {
                   2390:         $groupslist = join('","',sort(keys(%curr_groups)));
                   2391:     }
                   2392:     return <<"END";
                   2393: function validate(caller) {
                   2394:     var groups = new Array("$groupslist");
                   2395:     var secname = caller.value;
                   2396:     if ((secname == 'all') || (secname == 'none')) {
                   2397:         alert("'"+secname+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
                   2398:         return 'error';
                   2399:     }
                   2400:     if (secname != '') {
                   2401:         for (var k=0; k<groups.length; k++) {
                   2402:             if (secname == groups[k]) {
                   2403:                 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.");
                   2404:                 return 'error';
                   2405:             }
                   2406:         }
                   2407:     }
                   2408:     return 'ok';
                   2409: }
                   2410: END
                   2411: }
                   2412: 
1.50      matthew  2413: ###################################################################
                   2414: ###################################################################
                   2415: 
                   2416: =pod
                   2417: 
                   2418: =item &handler
                   2419: 
                   2420: The typical handler you see in all these modules.  Takes $r, the
                   2421: http request, as an argument.  
                   2422: 
                   2423: The response to the request is governed by two form variables
                   2424: 
                   2425:  form.action      form.state     response
                   2426:  ---------------------------------------------------
                   2427:  undefined        undefined      print main menu
                   2428:  upload           undefined      print courselist upload menu
                   2429:  upload           got_file       deal with uploaded file,
                   2430:                                  print the upload managing menu
                   2431:  upload           enrolling      enroll students based on upload
                   2432:  drop             undefined      print the classlist ready to drop
                   2433:  drop             done           drop the selected students
1.74      matthew  2434:  enrollstudent    undefined      print student username domain form
                   2435:  enrollstudent    gotusername    print single student enroll menu
1.50      matthew  2436:  enrollstudent    enrolling      enroll student
                   2437:  classlist        undefined      print html classlist
                   2438:  classlist        csv            print csv classlist
                   2439:  modifystudent    undefined      print classlist to select student to modify
                   2440:  modifystudent    selected       print modify student menu
                   2441:  modifystudent    done           make modifications to student record
                   2442: 
                   2443: =cut
                   2444: 
                   2445: ###################################################################
                   2446: ###################################################################
1.10      www      2447: sub handler {
1.26      matthew  2448:     my $r=shift;
                   2449:     if ($r->header_only) {
1.86      www      2450:         &Apache::loncommon::content_type($r,'text/html');
1.26      matthew  2451:         $r->send_http_header;
                   2452:         return OK;
                   2453:     }
1.48      matthew  2454:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.50      matthew  2455:                                             ['action','state']);
1.102     matthew  2456: 
                   2457:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   2458:     &Apache::lonhtmlcommon::add_breadcrumb
                   2459:         ({href=>"/adm/dropadd",
                   2460:           text=>"Enrollment Manager",
                   2461:           faq=>9,bug=>'Instructor Interface',});
1.26      matthew  2462:     #  Needs to be in a course
1.127     albertel 2463:     if (! ($env{'request.course.fn'})) {
1.121     matthew  2464:         # Not in a course
1.127     albertel 2465:         $env{'user.error.msg'}=
1.132     raeburn  2466:             "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ".
                   2467:                                   "or drop or add students";
1.50      matthew  2468:         return HTTP_NOT_ACCEPTABLE; 
                   2469:     }
                   2470:     #
1.121     matthew  2471:     my $view_permission = 
1.127     albertel 2472:         &Apache::lonnet::allowed('vcl',$env{'request.course.id'});
1.121     matthew  2473:     my $enrl_permission = 
1.127     albertel 2474:         &Apache::lonnet::allowed('cst',$env{'request.course.id'});
1.132     raeburn  2475: 
                   2476:     my $grp_view_permission =
                   2477:         &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
                   2478:     my $grp_manage_permission =
                   2479:         &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
                   2480: 
                   2481: 
                   2482:     if (! $grp_view_permission && ! $grp_manage_permission && 
                   2483:                                   ! $view_permission && ! $enrl_permission) {
1.127     albertel 2484:         $env{'user.error.msg'}=
1.132     raeburn  2485:      "/adm/coursegroups:cst:0:0:Cannot manage or view course groups, ".
                   2486:                                  "or drop or add students";
                   2487:         return HTTP_NOT_ACCEPTABLE;
1.121     matthew  2488:     }
1.132     raeburn  2489: 
1.121     matthew  2490:     #
1.50      matthew  2491:     # Only output the header information if they did not request csv format
                   2492:     #
1.103     matthew  2493:     # Start page
                   2494:     &Apache::loncommon::content_type($r,'text/html');
                   2495:     $r->send_http_header;
                   2496:     $r->print(&header());
1.50      matthew  2497:     #
                   2498:     # Main switch on form.action and form.state, as appropriate
1.127     albertel 2499:     if (! exists($env{'form.action'})) {
1.141     albertel 2500:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.132     raeburn  2501:         &print_main_menu($r,$enrl_permission,$view_permission,$grp_manage_permission,
                   2502:                          $grp_view_permission);
1.127     albertel 2503:     } elsif ($env{'form.action'} eq 'upload' && $enrl_permission) {
1.102     matthew  2504:         &Apache::lonhtmlcommon::add_breadcrumb
                   2505:             ({href=>'/adm/dropadd?action=upload&state=',
1.106     matthew  2506:               text=>"Upload Classlist"});
1.141     albertel 2507:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Upload Classlist',
                   2508: 						      'Course_Create_Class_List'));
1.127     albertel 2509:         if (! exists($env{'form.state'})) {
1.50      matthew  2510:             &print_first_courselist_upload_form($r);            
1.127     albertel 2511:         } elsif ($env{'form.state'} eq 'got_file') {
1.50      matthew  2512:             &print_upload_manager_form($r);
1.127     albertel 2513:         } elsif ($env{'form.state'} eq 'enrolling') {
                   2514:             if ($env{'form.datatoken'}) {
1.26      matthew  2515:                 &upfile_drop_add($r);
1.50      matthew  2516:             } else {
                   2517:                 # Hmmm, this is an error
1.26      matthew  2518:             }
1.50      matthew  2519:         } else {
                   2520:             &print_first_courselist_upload_form($r);            
1.26      matthew  2521:         }
1.127     albertel 2522:     } elsif ($env{'form.action'} eq 'drop' && $enrl_permission) {
1.102     matthew  2523:         &Apache::lonhtmlcommon::add_breadcrumb
                   2524:             ({href=>'/adm/dropadd?action=drop',
1.106     matthew  2525:               text=>"Drop Students"});
1.141     albertel 2526:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students',
                   2527: 						      'Course_Drop_Student'));
1.127     albertel 2528:         if (! exists($env{'form.state'})) {
1.51      matthew  2529:             &print_drop_menu($r);
1.127     albertel 2530:         } elsif ($env{'form.state'} eq 'done') {
1.26      matthew  2531:             &drop_student_list($r);
1.50      matthew  2532:         } else {
1.55      matthew  2533:             &print_drop_menu($r);
1.26      matthew  2534:         }
1.127     albertel 2535:     } elsif ($env{'form.action'} eq 'enrollstudent' && $enrl_permission) {
1.102     matthew  2536:         &Apache::lonhtmlcommon::add_breadcrumb
                   2537:             ({href=>'/adm/dropadd?action=enrollstudent',
1.106     matthew  2538:               text=>"Enroll Student"});
1.141     albertel 2539:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   2540: 						      'Course_Add_Student'));
1.127     albertel 2541:         if (! exists($env{'form.state'})) {
1.74      matthew  2542:             &get_student_username_domain_form($r);
1.127     albertel 2543:         } elsif ($env{'form.state'} eq 'gotusername') {
1.50      matthew  2544:             &print_enroll_single_student_form($r);
1.127     albertel 2545:         } elsif ($env{'form.state'} eq 'enrolling') {
1.26      matthew  2546:             &enroll_single_student($r);
1.50      matthew  2547:         } else {
1.74      matthew  2548:             &get_student_username_domain_form($r);
1.26      matthew  2549:         }
1.127     albertel 2550:     } elsif ($env{'form.action'} eq 'classlist' && $view_permission) {
1.102     matthew  2551:         &Apache::lonhtmlcommon::add_breadcrumb
                   2552:             ({href=>'/adm/dropadd?action=classlist',
1.106     matthew  2553:               text=>"View Classlist"});
1.141     albertel 2554:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('View Classlist',
                   2555: 						      'Course_View_Class_List'));
1.127     albertel 2556:         if (! exists($env{'form.state'})) {
1.103     matthew  2557:             &print_html_classlist($r,undef);
1.127     albertel 2558:         } elsif ($env{'form.state'} eq 'csv') {
1.103     matthew  2559:             &print_html_classlist($r,'csv');
1.127     albertel 2560:         } elsif ($env{'form.state'} eq 'excel') {
1.103     matthew  2561:             &print_html_classlist($r,'excel');
1.50      matthew  2562:         } else {
1.103     matthew  2563:             &print_html_classlist($r,undef);
1.50      matthew  2564:         }
1.127     albertel 2565:     } elsif ($env{'form.action'} eq 'modifystudent' && $enrl_permission) {
1.102     matthew  2566:         &Apache::lonhtmlcommon::add_breadcrumb
                   2567:             ({href=>'/adm/dropadd?action=modifystudent',
1.106     matthew  2568:               text=>"Modify Student Data"});
1.141     albertel 2569:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Modify Student Data',
                   2570: 						      'Course_Modify_Student_Data'));
1.127     albertel 2571:         if (! exists($env{'form.state'})) {
1.50      matthew  2572:             &print_html_classlist($r);
1.127     albertel 2573:         } elsif ($env{'form.state'} eq 'selected') {
1.50      matthew  2574:             &print_modify_student_form($r);
1.127     albertel 2575:         } elsif ($env{'form.state'} eq 'done') {
1.50      matthew  2576:             &modify_single_student($r);
                   2577:         } else {
                   2578:             &print_html_classlist($r);
                   2579:         }        
                   2580:     } else {
                   2581:         # We should not end up here, but I guess it is possible
                   2582:         &Apache::lonnet::logthis("Undetermined state in londropadd.pm.  ".
1.127     albertel 2583:                                  "form.action = ".$env{'form.action'}.
1.50      matthew  2584:                                  "Someone should fix this.");
1.141     albertel 2585:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.121     matthew  2586:         &print_main_menu($r,$enrl_permission,$view_permission);
1.50      matthew  2587:     }
                   2588:     #
                   2589:     # Finish up
1.138     albertel 2590:     $r->print('</form>'.&Apache::loncommon::end_page());
1.26      matthew  2591:     return OK;
1.1       www      2592: }
                   2593: 
1.50      matthew  2594: ###################################################################
                   2595: ###################################################################
                   2596: 
1.1       www      2597: 1;
                   2598: __END__
1.50      matthew  2599: 
1.1       www      2600: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>