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

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to drop and add students in courses 
                      3: #
1.153   ! raeburn     4: # $Id: londropadd.pm,v 1.152 2006/12/21 19:41:03 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
                    109:     my @domains = &Apache::loncommon::get_domains();
                    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.45      matthew   120:         my %servers = &Apache::loncommon::get_library_servers($dom);
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.45      matthew   769:             my %home_servers =&Apache::loncommon::get_library_servers($domain);
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.12      www       825: }
                    826: 
1.68      matthew   827: sub setup_date_selectors {
1.91      raeburn   828:     my ($starttime,$endtime,$mode) = @_;
1.68      matthew   829:     if (! defined($starttime)) {
                    830:         $starttime = time;
1.114     raeburn   831:         unless ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
1.127     albertel  832:             if (exists($env{'course.'.$env{'request.course.id'}.
1.68      matthew   833:                             '.default_enrollment_start_date'})) {
1.127     albertel  834:                 $starttime = $env{'course.'.$env{'request.course.id'}.
1.68      matthew   835:                                   '.default_enrollment_start_date'};
1.91      raeburn   836:             }
1.68      matthew   837:         }
                    838:     }
                    839:     if (! defined($endtime)) {
                    840:         $endtime = time+(6*30*24*60*60); # 6 months from now, approx
1.91      raeburn   841:         unless ($mode eq 'createcourse') {
1.127     albertel  842:             if (exists($env{'course.'.$env{'request.course.id'}.
1.68      matthew   843:                             '.default_enrollment_end_date'})) {
1.127     albertel  844:                 $endtime = $env{'course.'.$env{'request.course.id'}.
1.68      matthew   845:                                 '.default_enrollment_end_date'};
1.91      raeburn   846:             }
1.68      matthew   847:         }
                    848:     }
                    849:     my $startdateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    850:                                                             'startdate',
                    851:                                                             $starttime);
                    852:     my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    853:                                                           'enddate',
                    854:                                                           $endtime);
1.114     raeburn   855:     if ($mode eq 'create_enrolldates') {
                    856:         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    857:                                                             'startenroll',
                    858:                                                             $starttime);
                    859:         $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    860:                                                           'endenroll',
                    861:                                                           $endtime);
                    862:     }
                    863:     if ($mode eq 'create_defaultdates') {
1.91      raeburn   864:         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
1.114     raeburn   865:                                                             'startaccess',
1.91      raeburn   866:                                                             $starttime);
                    867:         $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
1.114     raeburn   868:                                                           'endaccess',
1.91      raeburn   869:                                                           $endtime);
                    870:     }
1.68      matthew   871:     return ($startdateform,$enddateform);
                    872: }
                    873: 
                    874: sub get_dates_from_form {
                    875:     my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
                    876:     my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate');
1.127     albertel  877:     if ($env{'form.no_end_date'}) {
1.68      matthew   878:         $enddate = 0;
                    879:     }
                    880:     return ($startdate,$enddate);
                    881: }
                    882: 
                    883: sub date_setting_table {
1.91      raeburn   884:     my ($starttime,$endtime,$mode) = @_;
                    885:     my ($startform,$endform)=&setup_date_selectors($starttime,$endtime,$mode);
1.68      matthew   886:     my $dateDefault = '<nobr>'.
1.131     albertel  887:         '<label><input type="checkbox" name="makedatesdefault" /> '.
                    888:         &mt('make these dates the default for future enrollment').'</label>';
1.114     raeburn   889:     if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
1.91      raeburn   890:         $dateDefault = '&nbsp;';
                    891:     }
1.131     albertel  892:     my $perpetual = '<nobr><label><input type="checkbox" name="no_end_date"';
1.68      matthew   893:     if (defined($endtime) && $endtime == 0) {
                    894:         $perpetual .= ' checked';
                    895:     }
1.131     albertel  896:     $perpetual.= ' /> '.&mt('no ending date').'</label></nobr>';
1.114     raeburn   897:     if ($mode eq 'create_enrolldates') {
                    898:         $perpetual = '&nbsp;';
                    899:     }
1.68      matthew   900:     my $result = '';
                    901:     $result .= "<table>\n";
1.94      sakharuk  902:     $result .= '<tr><td align="right">'.&mt('Starting Date').'</td>'.
1.68      matthew   903:         '<td>'.$startform.'</td>'.
                    904:         '<td>'.$dateDefault.'</td>'."</tr>\n";
1.94      sakharuk  905:     $result .= '<tr><td align="right">'.&mt('Ending Date').'</td>'.
1.68      matthew   906:         '<td>'.$endform.'</td>'.
                    907:         '<td>'.$perpetual.'</td>'."</tr>\n";
                    908:     $result .= "</table>\n";
                    909:     return $result;
                    910: }
                    911: 
                    912: sub make_dates_default {
                    913:     my ($startdate,$enddate) = @_;
                    914:     my $result = '';
1.127     albertel  915:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    916:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.68      matthew   917:     my $put_result = &Apache::lonnet::put('environment',
                    918:             {'default_enrollment_start_date'=>$startdate,
                    919:              'default_enrollment_end_date'  =>$enddate},$dom,$crs);
                    920:     if ($put_result eq 'ok') {
                    921:         $result .= "Set default start and end dates for course<br />";
1.69      matthew   922:         #
                    923:         # Refresh the course environment
1.140     albertel  924:         &Apache::lonnet::coursedescription($env{'request.course.id'},
                    925: 					   {'freshen_cache' => 1});
1.68      matthew   926:     } else {
1.94      sakharuk  927:         $result .= &mt('Unable to set default dates for course').":".$put_result.
1.68      matthew   928:             '<br />';
                    929:     }
                    930:     return $result;
                    931: }
                    932: 
1.74      matthew   933: ##
                    934: ## Single student enrollment routines (some of them)
                    935: ##
                    936: sub get_student_username_domain_form {
                    937:     my $r = shift;
                    938:     my $domform = &Apache::loncommon::select_dom_form
1.127     albertel  939:         ($env{'course.'.$env{'request.course.id'}.'.domain'},'cudomain',0);
1.94      sakharuk  940:     my %lt=&Apache::lonlocal::texthash(
                    941: 		    'eos'  => "Enroll One Student",
                    942: 		    'usr'  => "Username",
                    943:                     'dom'  => "Domain",
                    944:                     'been' => "Begin Enrollment",
                    945: 				       );
1.74      matthew   946:     $r->print(<<END);
                    947: <input type="hidden" name="action" value="enrollstudent" />
                    948: <input type="hidden" name="state"  value="gotusername" />
1.94      sakharuk  949: <h3>$lt{'eos'}</h3>
1.74      matthew   950: <table>
1.94      sakharuk  951: <tr><th>$lt{'usr'}:</th>
1.74      matthew   952:     <td><input type="text" name="cuname"  size="15" /></td></tr>
1.94      sakharuk  953: <tr><th>$lt{'dom'}:</th>
1.74      matthew   954:     <td>$domform</td></tr>
                    955: <tr><th>&nbsp;</th>
                    956:     <td>
1.94      sakharuk  957:     <input type="submit" name="Begin Enrollment" value="$lt{'been'}" />
1.74      matthew   958:     </td></tr>
                    959: </table>
1.120     albertel  960: <script type="text/javascript">
                    961: // the if prevents the script error if the browser can not handle this
                    962: if ( document.studentform.cuname ) { document.studentform.cuname.focus(); }
                    963: </script>
1.74      matthew   964: END
                    965:     return;
                    966: }
                    967: 
1.50      matthew   968: sub print_enroll_single_student_form {
1.10      www       969:     my $r=shift;
1.94      sakharuk  970:     $r->print("<h3>".&mt('Enroll One Student')."</h3>");
1.74      matthew   971:     #
1.150     albertel  972:     my $username = &LONCAPA::clean_username($env{'form.cuname'});
                    973:     my $domain   = &LONCAPA::clean_domain($env{'form.cudomain'});
1.74      matthew   974:     my $home = &Apache::lonnet::homeserver($username,$domain);
                    975:     # $new_user flags whether we are creating a new user or using an old one
                    976:     my $new_user = 1;
                    977:     if ($home ne 'no_host') {
                    978:         $new_user = 0;
                    979:     }
                    980:     #
                    981:     my $user_data_html = '';
                    982:     my $javascript_validations = '';
                    983:     if ($new_user) {
1.127     albertel  984:         my $defdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.74      matthew   985:         # Set up authentication forms
                    986:         my ($krbdef,$krbdefdom) =
1.75      matthew   987:             &Apache::loncommon::get_kerberos_defaults($domain);
1.89      matthew   988:         $javascript_validations=&javascript_validations('auth',$krbdefdom);
1.74      matthew   989:         my %param = ( formname => 'document.studentform',
                    990:                       kerb_def_dom => $krbdefdom,
                    991:                       kerb_def_auth => $krbdef
                    992:                       );
                    993:         my $krbform = &Apache::loncommon::authform_kerberos(%param);
                    994:         my $intform = &Apache::loncommon::authform_internal(%param);
                    995:         my $locform = &Apache::loncommon::authform_local(%param);
                    996:         #
                    997:         # Set up domain selection form
                    998:         my $homeserver_form = '';
                    999:         my %servers = &Apache::loncommon::get_library_servers($domain);
                   1000:         $homeserver_form = '<select name="lcserver" size="1">'."\n".
                   1001:             '<option value="default" selected>default</option>'."\n";
                   1002:         while (my ($servername,$serverdescription) = each (%servers)) {
                   1003:             $homeserver_form .= '<option value="'.$servername.'">'.
                   1004:                 $serverdescription."</option>\n";
                   1005:         }
                   1006:         $homeserver_form .= "</select>\n";
                   1007:         #
                   1008:         #
1.94      sakharuk 1009: 	my %lt=&Apache::lonlocal::texthash(
                   1010: 		       'udf'  => "User Data for",
                   1011:                        'fn'   => "First Name",
                   1012:                        'mn'   => "Middle Name",
                   1013:                        'ln'   => "Last Name",
                   1014:                        'gen'  => "Generation",
                   1015:                        'hs'   => "Home Server",
                   1016:                        'pswd' => "Password",
                   1017: 		       'psam' => "Please select an authentication mechanism",
1.124     www      1018:                        'mail' => "Email Address"
1.94      sakharuk 1019: 					   );
1.130     www      1020: 	my $authhelp=&Apache::loncommon::help_open_topic('Auth_Options');
1.74      matthew  1021:         $user_data_html = <<END;
1.94      sakharuk 1022: <h3>$lt{'udf'} $username\@$domain</h3>
1.74      matthew  1023: <table>
1.94      sakharuk 1024: <tr><th>$lt{'fn'}:</th>
1.74      matthew  1025:     <td><input type="text" name="cfirst"  size="15"></td></tr>
1.94      sakharuk 1026: <tr><th>$lt{'mn'}:</th>
1.74      matthew  1027:     <td><input type="text" name="cmiddle" size="15"></td></tr>
1.94      sakharuk 1028: <tr><th>$lt{'ln'}:</th>
1.74      matthew  1029:     <td><input type="text" name="clast"   size="15"></td></tr>
1.94      sakharuk 1030: <tr><th>$lt{'gen'}:</th>
1.74      matthew  1031:     <td><input type="text" name="cgen"    size="5"> </td></tr>
1.94      sakharuk 1032: <tr><th>$lt{'hs'}:</th>
1.74      matthew  1033:     <td>$homeserver_form</td></tr>
1.124     www      1034: <tr><th>$lt{'mail'}:</th>
                   1035:     <td><input type="text" name="emailaddress" size="20" /></td></tr>
1.74      matthew  1036: </table>
1.94      sakharuk 1037: <h3>$lt{'pswd'}</h3>
1.130     www      1038: $lt{'psam'}$authhelp
1.74      matthew  1039: <table>
                   1040: <p>
                   1041: $krbform
1.75      matthew  1042: <br />
1.74      matthew  1043: $intform
1.75      matthew  1044: <br />
1.74      matthew  1045: $locform
                   1046: </p>
                   1047: END
                   1048:     } else {
                   1049:         # User already exists.  Do not worry about authentication
                   1050:         my %uenv = &Apache::lonnet::dump('environment',$domain,$username);
1.89      matthew  1051:         $javascript_validations = &javascript_validations('noauth');
1.94      sakharuk 1052: 	my %lt=&Apache::lonlocal::texthash(
                   1053: 		       'udf'  => "User Data for",
                   1054:                        'fn'   => "First Name",
                   1055:                        'mn'   => "Middle Name",
                   1056:                        'ln'   => "Last Name",
                   1057:                        'gen'  => "Generation",
1.124     www      1058:                        'mail' => "Email Address",
1.94      sakharuk 1059: 					   );
1.74      matthew  1060:         $user_data_html = <<END;
1.94      sakharuk 1061: <h3>$lt{'udf'} $username\@$domain</h3>
1.74      matthew  1062: <input type="hidden" name="lcserver" value="default" />
                   1063: <table>
1.94      sakharuk 1064: <tr><th>$lt{'fn'}:</th>
1.74      matthew  1065:     <td>
                   1066:     <input type="text" name="cfirst" value="$uenv{'firstname'}" size="15" />
                   1067:     </td></tr>
1.94      sakharuk 1068: <tr><th>$lt{'mn'}:</th>
1.74      matthew  1069:     <td>
                   1070:     <input type="text" name="cmiddle" value="$uenv{'middlename'}" size="15" />
                   1071:     </td></tr>
1.94      sakharuk 1072: <tr><th>$lt{'ln'}:</th>
1.74      matthew  1073:     <td>
                   1074:     <input type="text" name="clast"value="$uenv{'lastname'}" size="15" />
                   1075:     </td></tr>
1.94      sakharuk 1076: <tr><th>$lt{'gen'}:</th>
1.74      matthew  1077:     <td>
                   1078:     <input type="text" name="cgen" value="$uenv{'generation'}" size="5" />
                   1079:     </td></tr>
1.124     www      1080: <tr><th>$lt{'mail'}:</th>
                   1081:     <td>
                   1082:     <input type="text" name="emailaddress" value="$uenv{'permanentemail'}" size="20" />
                   1083:     </td></tr>
1.74      matthew  1084: </table>
                   1085: END
                   1086:     }
1.68      matthew  1087:     my $date_table = &date_setting_table();
1.74      matthew  1088:         # Print it all out
1.94      sakharuk 1089:     my %lt=&Apache::lonlocal::texthash(
                   1090: 		   'cd'   => "Course Data",
1.142     raeburn  1091:                    'gs'   => "Section",
1.94      sakharuk 1092:                    'idsn' => "ID/Student Number",
                   1093:                    'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1094:                    'eas'  => "Enroll as student",
                   1095: 				       );
1.50      matthew  1096:     $r->print(<<END);
1.74      matthew  1097: <input type="hidden" name="action" value="enrollstudent" />
                   1098: <input type="hidden" name="state"  value="done" />
                   1099: <input type="hidden" name="cuname" value="$username" />
                   1100: <input type="hidden" name="lcdomain" value="$domain" />
1.28      matthew  1101: <script type="text/javascript" language="Javascript">
1.142     raeburn  1102: function verify(vf,sec_caller) {
1.12      www      1103:     var founduname=0;
                   1104:     var foundpwd=0;
                   1105:     var foundname=0;
                   1106:     var foundid=0;
                   1107:     var foundsec=0;
                   1108:     var tw;
1.26      matthew  1109:     if ((typeof(vf.cuname.value) !="undefined") && (vf.cuname.value!='') && 
1.31      matthew  1110: 	(typeof(vf.lcdomain.value)!="undefined") && (vf.lcdomain.value!='')) {
1.12      www      1111:         founduname=1;
                   1112:     }
1.14      harris41 1113:     if ((typeof(vf.cfirst.value)!="undefined") && (vf.cfirst.value!='') &&
1.26      matthew  1114: 	(typeof(vf.clast.value) !="undefined") && (vf.clast.value!='')) {
1.12      www      1115:         foundname=1;
                   1116:     }
1.14      harris41 1117:     if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) {
1.12      www      1118:         foundsec=1;
1.142     raeburn  1119:         if (validate(sec_caller) == "error") {
                   1120:             return;
                   1121:         }
1.12      www      1122:     }
1.14      harris41 1123:     if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) {
1.12      www      1124: 	foundid=1;
                   1125:     }
                   1126:     if (founduname==0) {
                   1127: 	alert('You need to specify at least the username and domain fields');
                   1128:         return;
                   1129:     }
1.24      albertel 1130:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
1.12      www      1131: }
                   1132: 
1.24      albertel 1133: $javascript_validations
1.12      www      1134: 
1.24      albertel 1135: function clearpwd(vf) {
                   1136:     //nothing else needs clearing
1.15      albertel 1137: }
                   1138: 
1.12      www      1139: </script>
1.11      www      1140: 
1.74      matthew  1141: $user_data_html
1.50      matthew  1142: 
1.94      sakharuk 1143: <h3>$lt{'cd'}</h3>
1.50      matthew  1144: 
1.94      sakharuk 1145: <p>$lt{'gs'}: <input type="text" name="csec" size="5" />
1.50      matthew  1146: <p>
1.68      matthew  1147: $date_table
1.50      matthew  1148: </p>
1.94      sakharuk 1149: <h3>$lt{'idsn'}</h3>
1.50      matthew  1150: <p>
1.94      sakharuk 1151: $lt{'idsn'}: <input type="text" name="cstid" size="10">
1.26      matthew  1152: </p><p>
1.131     albertel 1153: <label>
1.26      matthew  1154: <input type="checkbox" name="forceid" value="yes"> 
1.94      sakharuk 1155: $lt{'disn'}
1.131     albertel 1156: </label>
1.50      matthew  1157: </p><p>
1.142     raeburn  1158: <input type="button" onClick="verify(this.form,this.form.csec)" value="$lt{'eas'}">
1.26      matthew  1159: </p>
1.50      matthew  1160: END
                   1161:     return;
1.10      www      1162: }
                   1163: 
                   1164: # ========================================================= Menu Phase Two Drop
1.51      matthew  1165: sub print_drop_menu {
1.10      www      1166:     my $r=shift;
1.92      sakharuk 1167:     $r->print("<h3>".&mt('Drop Students')."</h3>");
1.127     albertel 1168:     my $cid=$env{'request.course.id'};
1.56      matthew  1169:     my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
                   1170:     if (! defined($classlist)) {
1.94      sakharuk 1171:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.51      matthew  1172:         return;
1.25      matthew  1173:     }
1.51      matthew  1174:     # Print out the available choices
1.56      matthew  1175:     &show_drop_list($r,$classlist,$keylist);
1.51      matthew  1176:     return;
1.11      www      1177: }
                   1178: 
1.40      matthew  1179: # ============================================== view classlist
1.50      matthew  1180: sub print_html_classlist {
1.103     matthew  1181:     my ($r,$mode) = @_;
1.127     albertel 1182:     if (! exists($env{'form.sortby'})) {
                   1183:         $env{'form.sortby'} = 'username';
1.57      matthew  1184:     }
1.147     albertel 1185:     if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.127     albertel 1186:         $env{'form.Status'} = 'Active';
1.57      matthew  1187:     }
                   1188:     my $status_select = &Apache::lonhtmlcommon::StatusOptions
1.127     albertel 1189:         ($env{'form.Status'});
1.150     albertel 1190:     my $cid =$env{'request.course.id'};
1.127     albertel 1191:     my $cdom=$env{'course.'.$cid.'.domain'};
                   1192:     my $cnum=$env{'course.'.$cid.'.num'};
1.103     matthew  1193:     #
                   1194:     # List course personnel
1.100     www      1195:     my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);
1.110     matthew  1196:     #
1.127     albertel 1197:     if (! defined($env{'form.output'}) ||
                   1198:         $env{'form.output'} !~ /^(csv|excel|html)$/ ) {
                   1199:         $env{'form.output'} = 'html';
1.110     matthew  1200:     }
                   1201:     #
1.139     albertel 1202:     $r->print('<br />'.&Apache::loncommon::start_data_table());
1.110     matthew  1203:     foreach my $role (sort keys %coursepersonnel) {
                   1204:         next if ($role =~ /^\s*$/);
1.139     albertel 1205: 	$r->print(&Apache::loncommon::start_data_table_row().
                   1206: 		  '<td>'.$role.'</td><td>');
1.110     matthew  1207:         foreach my $user (split(',',$coursepersonnel{$role})) {
                   1208: 	    my ($puname,$pudom)=split(':',$user);
1.100     www      1209: 	    $r->print(' '.&Apache::loncommon::aboutmewrapper(
1.110     matthew  1210:                                     &Apache::loncommon::plainname($puname,
                   1211:                                                                   $pudom),
                   1212:                                                              $puname,$pudom));
1.100     www      1213: 	}
1.139     albertel 1214:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.100     www      1215:     }
1.139     albertel 1216:     $r->print(&Apache::loncommon::end_data_table());
1.103     matthew  1217:     #
                   1218:     # Interface output
                   1219:     $r->print('<input type="hidden" name="action" value="'.
1.127     albertel 1220:               $env{'form.action'}.'" />');
1.103     matthew  1221:     $r->print("<p>\n");
1.127     albertel 1222:     if ($env{'form.action'} ne 'modifystudent') {
1.103     matthew  1223: 	my %lt=&Apache::lonlocal::texthash('csv' => "CSV",
                   1224:                                            'excel' => "Excel",
                   1225:                                            'html'  => 'HTML');
1.110     matthew  1226:         my $output_selector = '<select size="1" name="output" >';
1.103     matthew  1227:         foreach my $outputformat ('html','csv','excel') {
                   1228:             my $option = '<option value="'.$outputformat.'" ';
1.127     albertel 1229:             if ($outputformat eq $env{'form.output'}) {
1.104     matthew  1230:                 $option .= 'selected ';
1.103     matthew  1231:             }
                   1232:             $option .='>'.$lt{$outputformat}.'</option>';
                   1233:             $output_selector .= "\n".$option;
                   1234:         }
                   1235:         $output_selector .= '</select>';
                   1236:         $r->print(&mt('Output Format: [_1]',$output_selector).('&nbsp;'x3));
1.59      matthew  1237:     }
1.103     matthew  1238:     $r->print(&mt('Student Status: [_1]',$status_select)."\n");
1.105     matthew  1239:     $r->print('<input type="submit" value="'.&mt('Update Display').'" />'.
                   1240:               "\n</p>\n");
1.103     matthew  1241:     #
                   1242:     # Print the classlist
                   1243:     $r->print('<h2>'.&mt('Current Class List').'</h2>');
1.56      matthew  1244:     my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   1245:     if (! defined($classlist)) {
1.94      sakharuk 1246:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.40      matthew  1247:     } else {
                   1248:         # Print out the available choices
1.127     albertel 1249:         if ($env{'form.action'} eq 'modifystudent') {
1.110     matthew  1250:             &show_class_list($r,'view','modify',
1.127     albertel 1251:                              $env{'form.Status'},$classlist,$keylist);
1.110     matthew  1252:         } else {
1.127     albertel 1253:             &show_class_list($r,$env{'form.output'},'aboutme',
                   1254:                              $env{'form.Status'},$classlist,$keylist);
1.50      matthew  1255:         }
1.41      matthew  1256:     }
                   1257: }
                   1258: 
1.40      matthew  1259: # =================================================== Show student list to drop
                   1260: sub show_class_list {
1.110     matthew  1261:     my ($r,$mode,$linkto,$statusmode,$classlist,$keylist)=@_;
1.127     albertel 1262:     my $cid=$env{'request.course.id'};
1.142     raeburn  1263:     my $cdom = $env{'course.'.$cid.'.domain'};
                   1264:     my $cnum = $env{'course.'.$cid.'.num'};
                   1265:     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
                   1266:                                               $classlist,$keylist,$cdom,$cnum);
1.60      matthew  1267:     #
                   1268:     # Variables for excel output
1.104     matthew  1269:     my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);
1.60      matthew  1270:     #
1.103     matthew  1271:     # Variables for csv output
                   1272:     my ($CSVfile,$CSVfilename);
                   1273:     #
1.127     albertel 1274:     my $sortby = $env{'form.sortby'};
1.142     raeburn  1275:     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end|type)$/) {
1.53      matthew  1276:         $sortby = 'username';
                   1277:     }
1.134     raeburn  1278:     if (! exists($env{'form.displayphotos'})) {
                   1279:         $env{'form.displayphotos'} = 'off';
                   1280:     }
                   1281:     my $displayphotos = $env{'form.displayphotos'};
                   1282: 
1.42      matthew  1283:     # Print out header 
1.114     raeburn  1284:     unless ($mode eq 'autoenroll') {
                   1285:         $r->print(<<END);
1.127     albertel 1286: <input type="hidden" name="state" value="$env{'form.state'}" />
1.114     raeburn  1287: END
                   1288:     }
1.103     matthew  1289:     $r->print(<<END);
                   1290: <input type="hidden" name="sortby" value="$sortby" />
1.134     raeburn  1291: <input type="hidden" name="displayphotos" value="$displayphotos" />
1.103     matthew  1292: END
1.114     raeburn  1293:     if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') {
1.50      matthew  1294:         if ($linkto eq 'aboutme') {
1.142     raeburn  1295:             $r->print(&mt("Select a user name to view the user's personal page."));
1.50      matthew  1296:         } elsif ($linkto eq 'modify') {
1.142     raeburn  1297:             $r->print(&mt("Select a user name to modify the student's information"));
1.50      matthew  1298:         }
1.94      sakharuk 1299: 	my %lt=&Apache::lonlocal::texthash(
1.110     matthew  1300:                                            'usrn'   => "username",
                   1301:                                            'dom'    => "domain",
                   1302:                                            'sn'     => "student name",
                   1303:                                            'sec'    => "section",
1.142     raeburn  1304:                                            'grp'    => "active groups",
1.110     matthew  1305:                                            'start'  => "start date",
                   1306:                                            'end'    => "end date",
1.134     raeburn  1307:                                            'type'   => "enroll type/action",
                   1308:                                            'photo'  => "photo",
1.94      sakharuk 1309: 					   );
1.114     raeburn  1310:         unless ($mode eq 'autoenroll') {
                   1311:             $r->print(<<END);
1.59      matthew  1312: <input type="hidden" name="sname"  value="" />
                   1313: <input type="hidden" name="sdom"   value="" />
1.114     raeburn  1314: END
                   1315:         }
1.136     raeburn  1316:         if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
1.134     raeburn  1317:             $r->print('
                   1318: <script type="text/javascript">
                   1319: function photowindow(photolink) {
                   1320:     var title = "Photo_Viewer";
                   1321:     var options = "scrollbars=1,resizable=1,menubar=0";
                   1322:     options += ",width=240,height=240";
                   1323:     stdeditbrowser = open(photolink,title,options,"1");
                   1324:     stdeditbrowser.focus();
                   1325: }
                   1326: </script>
                   1327:            ');
                   1328:         }
1.115     raeburn  1329:         $r->print("
1.40      matthew  1330: <p>
1.139     albertel 1331: ".&Apache::loncommon::start_data_table()."
1.115     raeburn  1332: <tr>
                   1333:         ");
                   1334:         if ($mode eq 'autoenroll') {
                   1335:             $r->print("
                   1336:  <th><a href=\"javascript:document.studentform.sortby.value='type';document.studentform.submit();\">$lt{'type'}</a></th>
                   1337:             ");
                   1338:         } else {
                   1339:             $r->print("
                   1340: <th>Count</th>
                   1341:             ");
                   1342:         }
                   1343:         $r->print(<<END);
                   1344:     <th>
1.94      sakharuk 1345:        <a href="javascript:document.studentform.sortby.value='username';document.studentform.submit();">$lt{'usrn'}</a>
1.53      matthew  1346:     </th><th>
1.94      sakharuk 1347:        <a href="javascript:document.studentform.sortby.value='domain';document.studentform.submit();">$lt{'dom'}</a>
1.53      matthew  1348:     </th><th>
1.57      matthew  1349:        <a href="javascript:document.studentform.sortby.value='id';document.studentform.submit();">ID</a>
1.53      matthew  1350:     </th><th>
1.94      sakharuk 1351:        <a href="javascript:document.studentform.sortby.value='fullname';document.studentform.submit();">$lt{'sn'}</a>
1.53      matthew  1352:     </th><th>
1.94      sakharuk 1353:        <a href="javascript:document.studentform.sortby.value='section';document.studentform.submit();">$lt{'sec'}</a>
1.110     matthew  1354:     </th><th>
                   1355:        <a href="javascript:document.studentform.sortby.value='start';document.studentform.submit();">$lt{'start'}</a>
                   1356:     </th><th>
                   1357:        <a href="javascript:document.studentform.sortby.value='end';document.studentform.submit();">$lt{'end'}</a>
1.142     raeburn  1358:     </th><th>
                   1359:        <a href="javascript:document.studentform.sortby.value='groups';document.studentform.submit();">$lt{'grp'}</a>
1.53      matthew  1360:     </th>
1.40      matthew  1361: END
1.136     raeburn  1362:         if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
1.135     albertel 1363:             my %photo_options = &Apache::lonlocal::texthash(
1.134     raeburn  1364:                                                             'on' => 'Show',
                   1365:                                                             'off' => 'Hide',
                   1366:                                                             );
                   1367:             my $photochg = 'on';
                   1368:             if ($displayphotos eq 'on') {
                   1369:                 $photochg = 'off';
                   1370:             }
                   1371:             $r->print('    <th>'."\n".'     '. 
                   1372:             '<a href="javascript:document.studentform.displayphotos.value='.
                   1373:                       "'".$photochg."'".';document.studentform.submit();">'.
                   1374:                       $photo_options{$photochg}.'</a>&nbsp;'.$lt{'photo'}."\n".
                   1375:                       '    </th>'."\n");
                   1376:         }
                   1377:         $r->print("  </tr>\n");
1.41      matthew  1378:     } elsif ($mode eq 'csv') {
1.103     matthew  1379: 	#
                   1380: 	# Open a file
                   1381: 	$CSVfilename = '/prtspool/'.
1.127     albertel 1382: 	    $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
1.103     matthew  1383:             time.'_'.rand(1000000000).'.csv';
                   1384: 	unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {
                   1385: 	    $r->log_error("Couldn't open $CSVfilename for output $!");
                   1386: 	    $r->print("Problems occured in writing the csv file.  ".
                   1387: 		      "This error has been logged.  ".
                   1388: 		      "Please alert your LON-CAPA administrator.");
                   1389: 	    $CSVfile = undef;
                   1390: 	}
                   1391: 	#
                   1392: 	# Write headers and data to file
1.58      matthew  1393:         if($statusmode eq 'Expired') {
1.103     matthew  1394:             print $CSVfile '"'.&mt('Students with expired roles').'"'."\n";
1.58      matthew  1395:         }
1.147     albertel 1396:         if($statusmode eq 'Future') {
                   1397:             print $CSVfile '"'.&mt('Students with future roles').'"'."\n";
                   1398:         }
1.58      matthew  1399:         if ($statusmode eq 'Any') {
1.103     matthew  1400:             print $CSVfile '"'.join('","',map {
                   1401: 		&Apache::loncommon::csv_translate(&mt($_))
                   1402:                 } ("username","domain","ID","student name",
1.142     raeburn  1403:                    "section","start date","end date","status","active groups"))
                   1404:                   .'"'."\n";
1.58      matthew  1405:         } else {
1.103     matthew  1406:             print $CSVfile '"'.join('","',map {
                   1407: 		&Apache::loncommon::csv_translate(&mt($_))
                   1408:                 } ("username","domain","ID","student name",
1.142     raeburn  1409:                    "section","start date","end date","active groups")).'"'."\n";
1.58      matthew  1410:         }
1.60      matthew  1411:     } elsif ($mode eq 'excel') {
                   1412:         # Create the excel spreadsheet
1.126     matthew  1413:         ($excel_workbook,$excel_filename,$format) = 
                   1414:             &Apache::loncommon::create_workbook($r);
                   1415:         return if (! defined($excel_workbook));
1.60      matthew  1416:         $excel_sheet = $excel_workbook->addworksheet('classlist');
                   1417:         #
1.76      albertel 1418:         my $description = 'Class List for '.
1.127     albertel 1419:             $env{'course.'.$env{'request.course.id'}.'.description'};
1.104     matthew  1420:         $excel_sheet->write($row++,0,$description,$format->{'h1'});
1.60      matthew  1421:         #
                   1422:         $excel_sheet->write($row++,0,["username","domain","ID",
1.110     matthew  1423:                                       "student name","section",
1.142     raeburn  1424:                                       "start date","end date","status",
                   1425:                                       "active groups"],
1.110     matthew  1426:                             $format->{'bold'});
1.41      matthew  1427:     }
1.56      matthew  1428:     #
                   1429:     # Sort the students
                   1430:     my %index;
                   1431:     my $i;
                   1432:     foreach (@$keylist) {
                   1433:         $index{$_} = $i++;
                   1434:     }
1.142     raeburn  1435:     $index{'groups'} = scalar(@{$keylist});
1.56      matthew  1436:     my $index  = $index{$sortby};
                   1437:     my $second = $index{'username'};
                   1438:     my $third  = $index{'domain'};
1.53      matthew  1439:     my @Sorted_Students = sort {
1.56      matthew  1440:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   1441:             ||
                   1442:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   1443:             ||
                   1444:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   1445:         } (keys(%$classlist));
1.108     matthew  1446:     my $studentcount = 0;
1.115     raeburn  1447:     my $autocount = 0;
                   1448:     my $manualcount = 0;
                   1449:     my $unlockcount = 0;
                   1450:     my $lockcount = 0;
1.53      matthew  1451:     foreach my $student (@Sorted_Students) {
1.110     matthew  1452:         my $sdata = $classlist->{$student};
1.142     raeburn  1453:         my $groups = $classgroups->{$student};
1.110     matthew  1454:         my $username = $sdata->[$index{'username'}];
                   1455:         my $domain   = $sdata->[$index{'domain'}];
                   1456:         my $section  = $sdata->[$index{'section'}];
1.142     raeburn  1457:         my $active_groups;
                   1458:         if (ref($groups->{active}) eq 'HASH') {
                   1459:             $active_groups = join(', ',keys(%{$groups->{'active'}}));
                   1460:         }
1.110     matthew  1461:         my $name     = $sdata->[$index{'fullname'}];
                   1462:         my $id       = $sdata->[$index{'id'}];
                   1463:         my $status   = $sdata->[$index{'status'}];
                   1464:         my $start    = $sdata->[$index{'start'}];
                   1465:         my $end      = $sdata->[$index{'end'}];
1.115     raeburn  1466:         my $type     = $sdata->[$index{'type'}];
1.57      matthew  1467:         next if (($statusmode ne 'Any') && ($status ne $statusmode));
1.114     raeburn  1468:         if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
                   1469:             if (! defined($start) || $start == 0) {
                   1470:                 $start = &mt('none');
                   1471:             } else {
                   1472:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1473:             }
                   1474:             if (! defined($end) || $end == 0) {
                   1475:                 $end = &mt('none');
                   1476:             } else {
                   1477:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1478:             }
1.139     albertel 1479: 	    $r->print(&Apache::loncommon::start_data_table_row());
1.115     raeburn  1480:             if ($mode eq 'autoenroll') {
                   1481:                 my $lockedtype = $sdata->[$index{'lockedtype'}];
                   1482:                 $studentcount++;
                   1483:                 my $cellentry;
                   1484:                 if ($type eq 'auto') {
1.131     albertel 1485:                     $cellentry = '<b>'.&mt('auto').'</b>&nbsp;<label><input type="checkbox" name="chgauto" value="'.$username.':'.$domain.'" />&nbsp;Change</label>';
1.115     raeburn  1486:                     $autocount ++;
                   1487:                 } else {
1.131     albertel 1488:                     $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  1489:                     $manualcount ++;
                   1490:                     if ($lockedtype) {
1.131     albertel 1491:                         $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Unlock').'</label>';
1.115     raeburn  1492:                         $unlockcount ++;
                   1493:                     } else {
1.131     albertel 1494:                         $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Lock').'</label>';
1.115     raeburn  1495:                         $lockcount ++;
                   1496:                     }
1.118     raeburn  1497:                     $cellentry .= '</nobr></td></tr></table>';
1.115     raeburn  1498:                 }
                   1499:                 $r->print("<td>$cellentry<td>\n    ");
                   1500:             } else {
                   1501:                 $r->print("<td>".(++$studentcount)."</td><td>\n    ");
                   1502:             }
1.51      matthew  1503:             if ($linkto eq 'nothing') {
                   1504:                 $r->print($username);
                   1505:             } elsif ($linkto eq 'aboutme') {
                   1506:                 $r->print(&Apache::loncommon::aboutmewrapper($username,
                   1507:                                                              $username,
                   1508:                                                              $domain));
                   1509:             } elsif ($linkto eq 'modify') {
1.59      matthew  1510:                 $r->print('<a href="'.
                   1511:                           "javascript:document.studentform.sname.value='".
                   1512:                           $username.
                   1513:                           "';document.studentform.sdom.value='".$domain.
                   1514:                           "';document.studentform.state.value='selected".
                   1515:                           "';document.studentform.submit();".'">'.
1.53      matthew  1516:                           $username."</a>\n");
1.50      matthew  1517:             }
1.51      matthew  1518:             $r->print(<<"END");
1.50      matthew  1519:     </td>
1.51      matthew  1520:     <td>$domain</td>
                   1521:     <td>$id</td>
                   1522:     <td>$name</td>
                   1523:     <td>$section</td>
1.110     matthew  1524:     <td>$start</td>
                   1525:     <td>$end</td>
1.142     raeburn  1526:     <td>$active_groups</td>
1.114     raeburn  1527: END
1.134     raeburn  1528:             if ($env{'course.'.$env{'request.course.id'}.
1.136     raeburn  1529: 			 '.internal.showphoto'}) {
1.134     raeburn  1530:                 if ($displayphotos eq 'on') {
1.135     albertel 1531:                     my $imgurl = 
                   1532: 			&Apache::lonnet::retrievestudentphoto($domain,
                   1533: 							      $username,'gif',
                   1534: 							      'thumbnail');
1.134     raeburn  1535:                 
                   1536:                     $r->print('    <td align="right"><a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($domain,$username,'jpg')."'".')"><img src="'.$imgurl.'" border="1"></a></td>');
                   1537:                 } else {
                   1538:                     $r->print('    <td>&nbsp;</td>  ');
                   1539:                 }
                   1540:             }
1.139     albertel 1541: 	    $r->print(&Apache::loncommon::end_data_table_row());
1.51      matthew  1542:         } elsif ($mode eq 'csv') {
1.103     matthew  1543:             next if (! defined($CSVfile));
1.51      matthew  1544:             # no need to bother with $linkto
1.114     raeburn  1545:             if (! defined($start) || $start == 0) {
                   1546:                 $start = &mt('none');
                   1547:             } else {
                   1548:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1549:             }
                   1550:             if (! defined($end) || $end == 0) {
                   1551:                 $end = &mt('none');
                   1552:             } else {
                   1553:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1554:             }
1.51      matthew  1555:             my @line = ();
1.110     matthew  1556:             foreach ($username,$domain,$id,$name,$section,$start,$end) {
1.51      matthew  1557:                 push @line,&Apache::loncommon::csv_translate($_);
1.58      matthew  1558:             }
                   1559:             if ($statusmode eq 'Any') {
                   1560:                 push @line,&Apache::loncommon::csv_translate($status);
1.41      matthew  1561:             }
1.142     raeburn  1562:             push @line,&Apache::loncommon::csv_translate($active_groups);
1.103     matthew  1563:             print $CSVfile '"'.join('","',@line).'"'."\n";
1.60      matthew  1564:         } elsif ($mode eq 'excel') {
1.110     matthew  1565:             $excel_sheet->write($row,0,[$username,$domain,$id,
                   1566:                                           $name,$section]);
                   1567:             my $col = 5;
                   1568:             foreach my $time ($start,$end) {
1.129     matthew  1569:                 if (defined($time) && $time != 0) {
                   1570:                     $excel_sheet->write($row,$col++,
1.110     matthew  1571:                                    &Apache::lonstathelpers::calc_serial($time),
                   1572:                                     $format->{'date'});
1.129     matthew  1573:                 } else {
                   1574:                     $excel_sheet->write($row,$col++,'none');
                   1575:                 }                    
1.110     matthew  1576:             }
                   1577:             $excel_sheet->write($row,$col++,$status);
1.142     raeburn  1578:             $excel_sheet->write($row,$col++,$active_groups);
1.110     matthew  1579:             $row++;
1.40      matthew  1580:         }
                   1581:     }
1.114     raeburn  1582:     if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
1.139     albertel 1583: 	$r->print(&Apache::loncommon::end_data_table().'<br />');
1.60      matthew  1584:     } elsif ($mode eq 'excel') {
                   1585:         $excel_workbook->close();
                   1586:         $r->print('<p><a href="'.$excel_filename.'">'.
1.94      sakharuk 1587:                   &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
1.103     matthew  1588:     } elsif ($mode eq 'csv') {
                   1589:         close($CSVfile);
                   1590:         $r->print('<a href="'.$CSVfilename.'">'.
                   1591:                   &mt('Your CSV file').'</a> is ready for download.'.
                   1592:                   "\n");
                   1593:         $r->rflush();
1.60      matthew  1594:     }
1.114     raeburn  1595:     if ($mode eq 'autoenroll') {
1.115     raeburn  1596:         return ($studentcount,$autocount,$manualcount,$lockcount,$unlockcount);
1.114     raeburn  1597:     }
1.115     raeburn  1598:     return;
1.40      matthew  1599: }
                   1600: 
1.50      matthew  1601: 
                   1602: #
                   1603: # print out form for modification of a single students data
                   1604: #
                   1605: sub print_modify_student_form {
                   1606:     my $r = shift();
                   1607:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.59      matthew  1608:                                             ['sdom','sname']);    
1.127     albertel 1609:     my $sname  = $env{'form.sname'};
                   1610:     my $sdom   = $env{'form.sdom'};
                   1611:     my $sortby = $env{'form.sortby'};
1.50      matthew  1612:     # determine the students name information
                   1613:     my %info=&Apache::lonnet::get('environment',
                   1614:                                   ['firstname','middlename',
1.52      matthew  1615:                                    'lastname','generation','id'],
1.50      matthew  1616:                                   $sdom, $sname);
                   1617:     my ($tmp) = keys(%info);
                   1618:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1619:         $r->print('<font color="#ff0000" size="+2">'.&mt('Error').'</font>'.
1.50      matthew  1620:                   '<p>'.
1.94      sakharuk 1621:                   &mt('Unable to retrieve environment data for').' '.$sname.
                   1622:                   &mt('in domain').' '.$sdom.'</p><p>'.
1.138     albertel 1623:                   &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p>'.&Apache::loncommon::end_page());
1.50      matthew  1624:         return;
                   1625:     }
                   1626:     # determine the students starting and ending times and section
                   1627:     my ($starttime,$endtime,$section) = &get_enrollment_data($sname,$sdom);
1.87      matthew  1628:     if ($starttime =~ /^error/) {
1.94      sakharuk 1629:         $r->print('<h2>'&mt('Error').'</h2>');
1.87      matthew  1630:         $r->print('<p>'.$starttime.'</p>');
                   1631:         return;
                   1632:     }
1.101     matthew  1633:     #
1.50      matthew  1634:     # Deal with date forms
1.101     matthew  1635:     my $current_date_description = '';
                   1636:     my $textdate = '';
                   1637: 
                   1638:     if (! defined($starttime) || $starttime == 0) {
                   1639:         $current_date_description = &mt('Current Starting Date: not set').
                   1640:             '<br />';
                   1641:     } else {
                   1642:         $current_date_description = 
                   1643:             &mt('Current Starting Date: [_1]',
                   1644:                 &Apache::lonlocal::locallocaltime($starttime)).'<br />';
                   1645:     }
                   1646:     if (! defined($endtime) || $endtime == 0) {
                   1647:         $current_date_description.= &mt('Current Ending Date: not set').
                   1648:             '<br />';
                   1649:     } else {
                   1650:         $current_date_description.= 
                   1651:             &mt('Current Ending Date: [_1]',
                   1652:                 &Apache::lonlocal::locallocaltime($endtime)).'<br />';
                   1653: 
                   1654:     }
1.68      matthew  1655:     my $date_table = &date_setting_table($starttime,$endtime);
1.59      matthew  1656:     #
1.127     albertel 1657:     if (! exists($env{'form.Status'}) || 
1.147     albertel 1658:         $env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.127     albertel 1659:         $env{'form.Status'} = 'crap';
1.59      matthew  1660:     }
1.94      sakharuk 1661:     # Make sure student is enrolled in course
                   1662:     my %lt=&Apache::lonlocal::texthash(
                   1663: 	           'mef'   => "Modify Enrollment for",
                   1664:                    'odcc'  => "Only domain coordinators can change a users password.",
                   1665:                    'sn'    => "Student Name",
                   1666:                    'fn'    => "First",
                   1667:                    'mn'    => "Middle",
                   1668:                    'ln'    => "Last",
                   1669:                    'gen'   => "Generation",
                   1670:                    'sid'   => "Student ID",
                   1671:                    'disn'  => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1672:                    'sec'   => "Section",
                   1673:                    'sm'    => "Submit Modifications",
                   1674: 				       );
1.142     raeburn  1675: # Check if section name is valid
                   1676:     my $section_check = &section_check_js();
                   1677:     $r->print(<<"END");
                   1678: <script type="text/javascript">
                   1679: $section_check
                   1680: function secverify(formname,caller) {
                   1681:     if (validate(caller) == "error") {
                   1682:         return;
                   1683:     } else {
                   1684:         formname.submit();
                   1685:     }
                   1686: }
                   1687: </script>
1.52      matthew  1688: <p>
                   1689: <font size="+1">
1.94      sakharuk 1690: $lt{'odcc'}
1.52      matthew  1691: </font>
                   1692: </p>
1.50      matthew  1693: <input type="hidden" name="slogin"  value="$sname"  />
                   1694: <input type="hidden" name="sdomain" value="$sdom" />
                   1695: <input type="hidden" name="action"  value="modifystudent" />
1.53      matthew  1696: <input type="hidden" name="state"   value="done" />
                   1697: <input type="hidden" name="sortby"  value="$sortby" />
1.127     albertel 1698: <input type="hidden" name="Status"  value="$env{'form.Status'}" />
1.94      sakharuk 1699: <h2>$lt{'mef'} $info{'firstname'} $info{'middlename'} 
1.50      matthew  1700: $info{'lastname'} $info{'generation'}, $sname\@$sdom</h2>
                   1701: <p>
1.94      sakharuk 1702: <b>$lt{'sn'}</b>
1.50      matthew  1703: <table>
1.94      sakharuk 1704: <tr><th>$lt{'fn'}</th><th>$lt{'mn'}</th><th>$lt{'ln'}</th><th>$lt{'gen'}</th></tr>
1.50      matthew  1705: <tr><td>
                   1706: <input type="text" name="firstname"  value="$info{'firstname'}"  /></td><td>
                   1707: <input type="text" name="middlename" value="$info{'middlename'}" /></td><td>
                   1708: <input type="text" name="lastname"   value="$info{'lastname'}"   /></td><td>
                   1709: <input type="text" name="generation" value="$info{'generation'}" /></td></tr>
                   1710: </table>
                   1711: </p><p>
1.94      sakharuk 1712: <b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12"/>
1.52      matthew  1713: </p><p>
1.131     albertel 1714: <label>
1.53      matthew  1715: <input type="checkbox" name="forceid" > 
1.94      sakharuk 1716: $lt{'disn'}
1.131     albertel 1717: </label>
1.53      matthew  1718: </p><p>
1.101     matthew  1719: <b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="14"/>
1.50      matthew  1720: </p>
1.101     matthew  1721: <p>$current_date_description</p>
1.68      matthew  1722: <p>$date_table</p>
1.142     raeburn  1723: <input type="button" value="$lt{'sm'}" onClick="secverify(this.form,this.form.section)" />
1.50      matthew  1724: END
1.138     albertel 1725:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  1726:     return;
                   1727: }
                   1728: 
                   1729: #
                   1730: # modify a single students section 
                   1731: #
                   1732: sub modify_single_student {
1.138     albertel 1733:     my ($r) = @_;
1.68      matthew  1734:     #
1.80      matthew  1735:     # Remove non alphanumeric values from the section
1.127     albertel 1736:     $env{'form.section'} =~ s/\W//g;
1.77      matthew  1737:     #
1.68      matthew  1738:     # Do the date defaults first
                   1739:     my ($starttime,$endtime) = &get_dates_from_form();
1.127     albertel 1740:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  1741:         $r->print(&make_dates_default($starttime,$endtime));
                   1742:     }
1.59      matthew  1743:     # Get the 'sortby' and 'Status' variables so the user goes back to their
                   1744:     # previous screen
1.127     albertel 1745:     my $sortby = $env{'form.sortby'};
                   1746:     my $status = $env{'form.Status'};
1.53      matthew  1747:     #
                   1748:     # We always need this information
1.127     albertel 1749:     my $slogin     = $env{'form.slogin'};
                   1750:     my $sdom       = $env{'form.sdomain'};
1.53      matthew  1751:     #
                   1752:     # Get the old data
                   1753:     my %old=&Apache::lonnet::get('environment',
                   1754:                                  ['firstname','middlename',
                   1755:                                   'lastname','generation','id'],
                   1756:                                  $sdom, $slogin);
1.59      matthew  1757:     $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin,
1.127     albertel 1758:                                                   $env{'request.course.id'});
1.53      matthew  1759:     my ($tmp) = keys(%old);
                   1760:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1761:         $r->print(&mt('There was an error determining the environment values for')." $slogin \@ $sdom.");
1.53      matthew  1762:         return;
                   1763:     }
                   1764:     undef $tmp;
                   1765:     #
                   1766:     # Get the new data
1.127     albertel 1767:     my $firstname  = $env{'form.firstname'};
                   1768:     my $middlename = $env{'form.middlename'};
                   1769:     my $lastname   = $env{'form.lastname'};
                   1770:     my $generation = $env{'form.generation'};
                   1771:     my $section    = $env{'form.section'};
                   1772:     my $courseid   = $env{'request.course.id'};
                   1773:     my $sid        = $env{'form.id'};
1.50      matthew  1774:     my $displayable_starttime = localtime($starttime);
                   1775:     my $displayable_endtime   = localtime($endtime);
1.53      matthew  1776:     # 
                   1777:     # check for forceid override
1.63      matthew  1778:     if ((defined($old{'id'})) && ($old{'id'} ne '') && 
1.127     albertel 1779:         ($sid ne $old{'id'}) && (! exists($env{'form.forceid'}))) {
1.94      sakharuk 1780:         $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  1781:         $sid = $old{'id'};
                   1782:     }
                   1783:     #
1.50      matthew  1784:     # talk to the user about what we are going to do
1.94      sakharuk 1785:     my %lt=&Apache::lonlocal::texthash(
                   1786: 	           'mdu'   => "Modifying data for user",
                   1787:                    'si'    => "Student Information",
                   1788:                    'fd'    => "Field",
                   1789:                    'ov'    => "Old Value",
                   1790:                    'nv'    => "New Value",
                   1791:                    'fn'    => "First name",
                   1792:                    'mn'    => "Middle name",
                   1793:                    'ln'    => "Last name",
                   1794:                    'gen'   => "Generation",
                   1795:                    'sec'   => "Section",
                   1796:                    'ri'    => "Role Information",
                   1797:                    'st'    => "Start Time",
                   1798:                    'et'    => "End Time",
                   1799: 				       );
1.50      matthew  1800:     $r->print(<<END);
1.94      sakharuk 1801:     <h2>$lt{'mdu'} $slogin \@ $sdom </h2>
                   1802: <h3>$lt{'si'}</h3>
1.53      matthew  1803: <table rules="rows" border="1" cellpadding="3" >
                   1804: <tr>
1.94      sakharuk 1805:     <th> $lt{'fd'} </th>
                   1806:     <th> $lt{'ov'} </th>
                   1807:     <th> $lt{'nv'} </th>
1.53      matthew  1808: </tr>
                   1809: <tr>
1.94      sakharuk 1810:     <td> <b>$lt{'fn'}</b> </td>
1.53      matthew  1811:     <td> $old{'firstname'} </td>
                   1812:     <td> $firstname </td>
                   1813: </tr><tr>
1.94      sakharuk 1814:     <td> <b>$lt{'mn'}</b> </td>
1.53      matthew  1815:     <td> $old{'middlename'} </td>
                   1816:     <td> $middlename </td>
                   1817: </tr><tr>
1.94      sakharuk 1818:     <td> <b>$lt{'ln'}</b> </td>
1.53      matthew  1819:     <td> $old{'lastname'} </td>
                   1820:     <td> $lastname </td>
                   1821: </tr><tr>
1.94      sakharuk 1822:     <td> <b>$lt{'gen'}</b> </td>
1.53      matthew  1823:     <td> $old{'generation'} </td>
                   1824:     <td> $generation </td>
                   1825: </tr><tr>
                   1826:     <td> <b>ID</b> </td>
                   1827:     <td> $old{'id'} </td>
                   1828:     <td> $sid </td>
1.59      matthew  1829: </tr><tr>
1.94      sakharuk 1830:     <td> <b>$lt{'sec'}</b> </td>
1.59      matthew  1831:     <td> $old{'section'} </td>
                   1832:     <td> $section</td>
1.53      matthew  1833: </tr>
1.50      matthew  1834: </table>
1.94      sakharuk 1835: <h3>$lt{'ri'}</h3>
1.50      matthew  1836: <table>
1.94      sakharuk 1837: <tr><td align="right"><b>$lt{'st'}:</b></td><td> $displayable_starttime </td></tr>
                   1838: <tr><td align="right"><b>$lt{'et'}:</b></td><td> $displayable_endtime   </td></tr>
1.50      matthew  1839: </table>
1.52      matthew  1840: <p>
1.50      matthew  1841: END
1.53      matthew  1842:     #
1.63      matthew  1843:     # Send request(s) to modify data (final undef is for 'desiredhost',
                   1844:     # which is a moot point because the student already has an account.
                   1845:     my $modify_section_results = &modifystudent($sdom,$slogin,
1.127     albertel 1846:                                                 $env{'request.course.id'},
1.63      matthew  1847:                                                 $section,undef);
                   1848:     if ($modify_section_results !~ /^ok/) {
1.94      sakharuk 1849:         $r->print(&mt('An error occured during the attempt to change the section for this student.')."<br />");
1.63      matthew  1850:     }
1.52      matthew  1851:     my $roleresults = &Apache::lonnet::modifystudent
1.53      matthew  1852:         ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname,
1.127     albertel 1853:          $generation,$section,$endtime,$starttime,$env{'form.forceid'});
1.53      matthew  1854:     if ($roleresults eq 'refused' ) {
1.94      sakharuk 1855:         $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  1856:     } elsif ($roleresults !~ /ok/) {
1.94      sakharuk 1857:         $r->print(&mt('An error occurred during the attempt to change the role information for this student.')."  <br />".
                   1858:                   &mt('The error reported was')." ".
1.50      matthew  1859:                   $roleresults);
1.53      matthew  1860:         &Apache::lonnet::logthis("londropadd:failed attempt to modify student".
                   1861:                                  " data for ".$slogin." \@ ".$sdom." by ".
1.127     albertel 1862:                                  $env{'user.name'}." \@ ".$env{'user.domain'}.
1.53      matthew  1863:                                  ":".$roleresults);
1.50      matthew  1864:     } else { # everything is okay!
1.94      sakharuk 1865:         $r->print(&mt('Student information updated successfully.')." <br />".
                   1866:                   &mt('The student must log out and log in again to see these changes.'));
1.50      matthew  1867:     }
1.94      sakharuk 1868:     my $Masd=&mt('Modify another students data');
1.50      matthew  1869:     $r->print(<<END);
1.52      matthew  1870: </p><p>
1.59      matthew  1871: <input type="hidden" name="action" value="modifystudent" />
                   1872: <input type="hidden" name="sortby" value="$sortby" />
                   1873: <input type="hidden" name="Status" value="$status" />
1.94      sakharuk 1874: <a href="javascript:document.studentform.submit();">$Masd</a>
1.50      matthew  1875: END
1.138     albertel 1876:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  1877:     return;
                   1878: }
                   1879: 
                   1880: sub get_enrollment_data {
                   1881:     my ($sname,$sdomain) = @_;
1.127     albertel 1882:     my $courseid = $env{'request.course.id'};
1.151     albertel 1883:     my $cdom = $env{'course.'.$courseid.'.domain'};
                   1884:     my $cnum = $env{'course.'.$courseid.'.num'};
1.50      matthew  1885:     my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname);
                   1886:     my ($tmp) = keys(%roles);
                   1887:     # Bail out if we were unable to get the students roles
1.87      matthew  1888:     return ('error'.$tmp) if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.50      matthew  1889:     # Go through the roles looking for enrollment in this course
                   1890:     my ($end,$start) = (undef,undef);
                   1891:     my $section = '';
                   1892:     my $count = scalar(keys(%roles));
                   1893:     while (my ($course,$role) = each(%roles)) {
1.150     albertel 1894:         if ($course=~m{^/\Q$cdom\E/\Q$cnum\E/*\s*(\w+)*_st$} ) {
1.50      matthew  1895:             #
                   1896:             # Get active role
                   1897:             $section=$1;
                   1898:             (undef,$end,$start)=split(/\_/,$role);
                   1899:             my $now=time;
                   1900:             my $notactive=0;
                   1901:             if ($start) {
                   1902:                 if ($now<$start) { $notactive=1; }
                   1903:             }
                   1904:             if ($end) {
                   1905:                 if ($now>$end) { $notactive=1; }
                   1906:             } 
                   1907:             unless ($notactive) { return ($start,$end,$section); }
                   1908:         }
                   1909:     }
                   1910:     return ($start,$end,$section);
                   1911: }
                   1912: 
1.56      matthew  1913: #################################################
                   1914: #################################################
                   1915: 
                   1916: =pod
                   1917: 
                   1918: =item show_drop_list
                   1919: 
                   1920: Display a list of students to drop
                   1921: Inputs: 
                   1922: 
                   1923: =over 4
                   1924: 
                   1925: =item $r, Apache request
                   1926: 
                   1927: =item $classlist, hash pointer returned from loncoursedata::get_classlist();
                   1928: 
                   1929: =item $keylist, array pointer returned from loncoursedata::get_classlist() 
                   1930: which describes the order elements are stored in the %$classlist values.
                   1931: 
                   1932: =item $nosort, if true, sorting links are omitted.
                   1933: 
                   1934: =back
                   1935: 
                   1936: =cut
                   1937: 
                   1938: #################################################
                   1939: #################################################
1.11      www      1940: sub show_drop_list {
1.56      matthew  1941:     my ($r,$classlist,$keylist,$nosort)=@_;
1.127     albertel 1942:     my $cid=$env{'request.course.id'};
                   1943:     if (! exists($env{'form.sortby'})) {
1.59      matthew  1944:         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   1945:                                                 ['sortby']);
                   1946:     }
1.127     albertel 1947:     my $sortby = $env{'form.sortby'};
1.142     raeburn  1948:     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) {
1.54      matthew  1949:         $sortby = 'username';
                   1950:     }
1.142     raeburn  1951:     my $cdom = $env{'course.'.$cid.'.domain'};
                   1952:     my $cnum = $env{'course.'.$cid,'.num'};
                   1953:     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
1.143     raeburn  1954:                                               $classlist,$keylist,$cdom,$cnum);
1.56      matthew  1955:     #
1.54      matthew  1956:     my $action = "drop";
                   1957:     $r->print(<<END);
                   1958: <input type="hidden" name="sortby" value="$sortby" />
                   1959: <input type="hidden" name="action" value="$action" />
1.50      matthew  1960: <input type="hidden" name="state"  value="done" />
1.32      matthew  1961: <script>
1.51      matthew  1962: function checkAll(field) {
1.32      matthew  1963:     for (i = 0; i < field.length; i++)
                   1964:         field[i].checked = true ;
                   1965: }
                   1966: 
1.51      matthew  1967: function uncheckAll(field) {
1.32      matthew  1968:     for (i = 0; i < field.length; i++)
                   1969:         field[i].checked = false ;
                   1970: }
                   1971: </script>
                   1972: <p>
1.26      matthew  1973: <input type="hidden" name="phase" value="four">
1.56      matthew  1974: END
                   1975: 
1.110     matthew  1976: my %lt=&Apache::lonlocal::texthash('usrn'   => "username",
                   1977:                                    'dom'    => "domain",
                   1978:                                    'sn'     => "student name",
                   1979:                                    'sec'    => "section",
                   1980:                                    'start'  => "start date",
                   1981:                                    'end'    => "end date",
1.142     raeburn  1982:                                    'groups' => "active groups",
1.110     matthew  1983:                                    );
1.56      matthew  1984:     if ($nosort) {
1.139     albertel 1985: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  1986:         $r->print(<<END);
                   1987: <tr>
                   1988:     <th>&nbsp;</th>
1.94      sakharuk 1989:     <th>$lt{'usrn'}</th>
                   1990:     <th>$lt{'dom'}</th>
1.56      matthew  1991:     <th>ID</th>
1.94      sakharuk 1992:     <th>$lt{'sn'}</th>
                   1993:     <th>$lt{'sec'}</th>
1.110     matthew  1994:     <th>$lt{'start'}</th>
                   1995:     <th>$lt{'end'}</th>
1.142     raeburn  1996:     <th>$lt{'groups'}</th>
1.56      matthew  1997: </tr>
                   1998: END
                   1999: 
                   2000:     } else  {
1.139     albertel 2001: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  2002:         $r->print(<<END);
1.54      matthew  2003: <tr><th>&nbsp;</th>
                   2004:     <th>
1.94      sakharuk 2005:        <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a>
1.54      matthew  2006:     </th><th>
1.94      sakharuk 2007:        <a href="/adm/dropadd?action=$action&sortby=domain">$lt{'dom'}</a>
1.54      matthew  2008:     </th><th>
                   2009:        <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
                   2010:     </th><th>
1.94      sakharuk 2011:        <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a>
1.54      matthew  2012:     </th><th>
1.94      sakharuk 2013:        <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a>
1.110     matthew  2014:     </th><th>
                   2015:        <a href="/adm/dropadd?action=$action&sortby=start">$lt{'start'}</a>
                   2016:     </th><th>
                   2017:        <a href="/adm/dropadd?action=$action&sortby=end">$lt{'end'}</a>
1.142     raeburn  2018:     </th><th>
                   2019:        <a href="/adm/dropadd?action=$action&sortby=groups">$lt{'groups'}</a>
1.54      matthew  2020:     </th>
                   2021: </tr>
1.26      matthew  2022: END
1.56      matthew  2023:     }
                   2024:     #
                   2025:     # Sort the students
                   2026:     my %index;
                   2027:     my $i;
                   2028:     foreach (@$keylist) {
                   2029:         $index{$_} = $i++;
                   2030:     }
1.142     raeburn  2031:     $index{'groups'} = scalar(@$keylist);
1.56      matthew  2032:     my $index  = $index{$sortby};
                   2033:     my $second = $index{'username'};
                   2034:     my $third  = $index{'domain'};
1.54      matthew  2035:     my @Sorted_Students = sort {
1.56      matthew  2036:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   2037:             ||
                   2038:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   2039:             ||
                   2040:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   2041:         } (keys(%$classlist));
1.54      matthew  2042:     foreach my $student (@Sorted_Students) {
1.52      matthew  2043:         my $error;
1.110     matthew  2044:         my $sdata = $classlist->{$student};
                   2045:         my $username = $sdata->[$index{'username'}];
                   2046:         my $domain   = $sdata->[$index{'domain'}];
                   2047:         my $section  = $sdata->[$index{'section'}];
                   2048:         my $name     = $sdata->[$index{'fullname'}];
                   2049:         my $id       = $sdata->[$index{'id'}];
                   2050:         my $start    = $sdata->[$index{'start'}];
                   2051:         my $end      = $sdata->[$index{'end'}];
1.142     raeburn  2052:         my $groups = $classgroups->{$student};
                   2053:         my $active_groups;
                   2054:         if (ref($groups->{active}) eq 'HASH') {
                   2055:             $active_groups = join(', ',keys(%{$groups->{'active'}}));
                   2056:         }
1.110     matthew  2057:         if (! defined($start) || $start == 0) {
                   2058:             $start = &mt('none');
                   2059:         } else {
                   2060:             $start = &Apache::lonlocal::locallocaltime($start);
                   2061:         }
                   2062:         if (! defined($end) || $end == 0) {
                   2063:             $end = &mt('none');
                   2064:         } else {
                   2065:             $end = &Apache::lonlocal::locallocaltime($end);
                   2066:         }
                   2067:         my $status   = $sdata->[$index{'status'}];
1.51      matthew  2068:         next if ($status ne 'Active');
                   2069:         #
1.139     albertel 2070:         $r->print(&Apache::loncommon::start_data_table_row());
1.51      matthew  2071:         $r->print(<<"END");
                   2072:     <td><input type="checkbox" name="droplist" value="$student"></td>
                   2073:     <td>$username</td>
                   2074:     <td>$domain</td>
                   2075:     <td>$id</td>
                   2076:     <td>$name</td>
                   2077:     <td>$section</td>
1.110     matthew  2078:     <td>$start</td>
                   2079:     <td>$end</td>
1.142     raeburn  2080:     <td>$active_groups</td>
1.26      matthew  2081: END
1.139     albertel 2082:         $r->print(&Apache::loncommon::end_data_table_row());
1.25      matthew  2083:     }
1.139     albertel 2084:     $r->print(&Apache::loncommon::end_data_table().'<br />');
1.111     matthew  2085:     %lt=&Apache::lonlocal::texthash(
1.94      sakharuk 2086: 	               'dp'   => "Drop Students",
                   2087:                        'ca'   => "check all",
                   2088:                        'ua'   => "uncheck all",
                   2089: 				       );
1.32      matthew  2090:     $r->print(<<"END");
                   2091: </p><p>
1.94      sakharuk 2092: <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)"> &nbsp;
                   2093: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)"> 
                   2094: <p><input type=submit value="$lt{'dp'}"></p>
1.32      matthew  2095: END
1.51      matthew  2096:     return;
1.10      www      2097: }
                   2098: 
1.48      matthew  2099: #
                   2100: # Print out the initial form to get the courselist file
                   2101: #
                   2102: sub print_first_courselist_upload_form {
                   2103:     my $r=shift;
1.88      matthew  2104:     my $str;
                   2105:     $str  = '<input type="hidden" name="phase" value="two">';
                   2106:     $str .= '<input type="hidden" name="action" value="upload" />';
                   2107:     $str .= '<input type="hidden"   name="state"  value="got_file" />';
                   2108:     $str .= "<h3>".&mt('Upload a class list')."</h3>\n";
                   2109:     $str .= &Apache::loncommon::upfile_select_html();
                   2110:     $str .= "<p>\n";
                   2111:     $str .= '<input type="submit" name="fileupload" value="'.
                   2112:         &mt('Upload class list').'">'."\n";
1.131     albertel 2113:     $str .= '<label><input type="checkbox" name="noFirstLine" /> '.
                   2114:         &mt('Ignore First Line')."</label></p>\n";
1.88      matthew  2115:     $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
1.92      sakharuk 2116:                          &mt("How do I create a class list from a spreadsheet")).
1.88      matthew  2117:                              "<br />\n";
                   2118:     $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
1.92      sakharuk 2119:                            &mt("How do I create a CSV file from a spreadsheet")).
1.88      matthew  2120:                                "<br />\n";
1.138     albertel 2121:     $str .= &Apache::loncommon::end_page();
1.88      matthew  2122:     $r->print($str);
1.48      matthew  2123:     return;
                   2124: }
                   2125: 
1.10      www      2126: # ================================================= Drop/Add from uploaded file
                   2127: sub upfile_drop_add {
                   2128:     my $r=shift;
1.24      albertel 2129:     &Apache::loncommon::load_tmp_file($r);
                   2130:     my @studentdata=&Apache::loncommon::upfile_record_sep();
1.127     albertel 2131:     if($env{'form.noFirstLine'}){shift(@studentdata);}
                   2132:     my @keyfields = split(/\,/,$env{'form.keyfields'});
                   2133:     my $cid = $env{'request.course.id'};
1.25      matthew  2134:     my %fields=();
1.127     albertel 2135:     for (my $i=0; $i<=$env{'form.nfields'}; $i++) {
                   2136:         if ($env{'form.upfile_associate'} eq 'reverse') {
                   2137:             if ($env{'form.f'.$i} ne 'none') {
                   2138:                 $fields{$keyfields[$i]}=$env{'form.f'.$i};
1.25      matthew  2139:             }
                   2140:         } else {
1.127     albertel 2141:             $fields{$env{'form.f'.$i}}=$keyfields[$i];
1.25      matthew  2142:         }
                   2143:     }
1.99      matthew  2144:     #
                   2145:     # Store the field choices away
                   2146:     foreach my $field (qw/username names 
                   2147:                        fname mname lname gen id sec ipwd email/) {
1.127     albertel 2148:         $env{'form.'.$field.'_choice'}=$fields{$field};
1.99      matthew  2149:     }
                   2150:     &Apache::loncommon::store_course_settings('enrollment_upload',
                   2151:                                               { 'username_choice' => 'scalar',
                   2152:                                                 'names_choice' => 'scalar',
                   2153:                                                 'fname_choice' => 'scalar',
                   2154:                                                 'mname_choice' => 'scalar',
                   2155:                                                 'lname_choice' => 'scalar',
                   2156:                                                 'gen_choice' => 'scalar',
                   2157:                                                 'id_choice' => 'scalar',
                   2158:                                                 'sec_choice' => 'scalar',
                   2159:                                                 'ipwd_choice' => 'scalar',
                   2160:                                                 'email_choice' => 'scalar' });
                   2161: 
1.26      matthew  2162:     #
1.68      matthew  2163:     my ($startdate,$enddate) = &get_dates_from_form();
1.127     albertel 2164:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  2165:         $r->print(&make_dates_default($startdate,$enddate));
                   2166:     }
1.31      matthew  2167:     # Determine domain and desired host (home server)
1.127     albertel 2168:     my $domain=$env{'form.lcdomain'};
                   2169:     my $desiredhost = $env{'form.lcserver'};
1.31      matthew  2170:     if (lc($desiredhost) eq 'default') {
                   2171:         $desiredhost = undef;
                   2172:     } else {
1.45      matthew  2173:         my %home_servers = &Apache::loncommon::get_library_servers($domain);
1.31      matthew  2174:         if (! exists($home_servers{$desiredhost})) {
1.88      matthew  2175:             $r->print('<font color="#ff0000">'.&mt('Error').'</font>'.
                   2176:                       &mt('Invalid home server specified'));
1.138     albertel 2177:             $r->print(&Apache::loncommon::end_page());
1.31      matthew  2178:             return;
                   2179:         }
                   2180:     }
1.26      matthew  2181:     # Determine authentication mechanism
                   2182:     my $amode  = '';
                   2183:     my $genpwd = '';
1.127     albertel 2184:     if ($env{'form.login'} eq 'krb') {
1.47      albertel 2185:         $amode='krb';
1.127     albertel 2186: 	$amode.=$env{'form.krbver'};
                   2187:         $genpwd=$env{'form.krbarg'};
                   2188:     } elsif ($env{'form.login'} eq 'int') {
1.25      matthew  2189:         $amode='internal';
1.127     albertel 2190:         if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
                   2191:             $genpwd=$env{'form.intarg'};
1.25      matthew  2192:         }
1.127     albertel 2193:     } elsif ($env{'form.login'} eq 'loc') {
1.25      matthew  2194:         $amode='localauth';
1.127     albertel 2195:         if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {
                   2196:             $genpwd=$env{'form.locarg'};
1.79      matthew  2197:         }
                   2198:     }
                   2199:     if ($amode =~ /^krb/) {
                   2200:         if (! defined($genpwd) || $genpwd eq '') {
                   2201:             $r->print('<font color="red" size="+1">'.
1.88      matthew  2202:                       &mt('Unable to enroll students').'</font>  '.
                   2203:                       &mt('No Kerberos domain was specified.').'</p>');
1.79      matthew  2204:             $amode = ''; # This causes the loop below to be skipped
1.25      matthew  2205:         }
                   2206:     }
1.150     albertel 2207:     if ( $domain eq &clean_domain($domain)
                   2208: 	&& ($amode ne '')) {
1.26      matthew  2209:         #######################################
                   2210:         ##         Enroll Students           ##
                   2211:         #######################################
1.88      matthew  2212:         $r->print('<h3>'.&mt('Enrolling Students')."</h3>\n<p>\n");
1.25      matthew  2213:         my $count=0;
                   2214:         my $flushc=0;
                   2215:         my %student=();
1.142     raeburn  2216:         # Get information about course groups
1.143     raeburn  2217:         my %curr_groups = &Apache::longroup::coursegroups();
1.26      matthew  2218:         # Get new classlist
1.25      matthew  2219:         foreach (@studentdata) {
                   2220:             my %entries=&Apache::loncommon::record_sep($_);
1.26      matthew  2221:             # Determine student name
1.25      matthew  2222:             unless (($entries{$fields{'username'}} eq '') ||
                   2223:                     (!defined($entries{$fields{'username'}}))) {
1.26      matthew  2224:                 my ($fname, $mname, $lname,$gen) = ('','','','');
1.25      matthew  2225:                 if (defined($fields{'names'})) {
1.26      matthew  2226:                     ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
                   2227:                                             /([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.25      matthew  2228:                 } else {
                   2229:                     if (defined($fields{'fname'})) {
                   2230:                         $fname=$entries{$fields{'fname'}};
                   2231:                     }
                   2232:                     if (defined($fields{'mname'})) {
                   2233:                         $mname=$entries{$fields{'mname'}};
                   2234:                     }
                   2235:                     if (defined($fields{'lname'})) {
                   2236:                         $lname=$entries{$fields{'lname'}};
                   2237:                     }
                   2238:                     if (defined($fields{'gen'})) {
                   2239:                         $gen=$entries{$fields{'gen'}};
                   2240:                     }
                   2241:                 }
1.150     albertel 2242:                 if ($entries{$fields{'username'}}
                   2243: 		    ne &LONCAPA::clean_username($entries{$fields{'username'}})) {
1.88      matthew  2244:                     $r->print('<br />'.
                   2245:       &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
                   2246:           $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
                   2247:                               '</b>');
1.25      matthew  2248:                 } else {
1.26      matthew  2249:                     # determine section number
1.25      matthew  2250:                     my $sec='';
                   2251:                     my $username=$entries{$fields{'username'}};
                   2252:                     if (defined($fields{'sec'})) {
                   2253:                         if (defined($entries{$fields{'sec'}})) {
                   2254:                             $sec=$entries{$fields{'sec'}};
                   2255:                         }
                   2256:                     }
1.80      matthew  2257:                     # remove non alphanumeric values from section
                   2258:                     $sec =~ s/\W//g;
1.142     raeburn  2259:                     if ($sec eq "none" || $sec eq 'all') {
                   2260:                         $r->print('<br />'.
                   2261:       &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a reserved word.',
                   2262:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2263:                         next;
                   2264:                     } elsif (($sec ne '') && (exists($curr_groups{$sec}))) {
                   2265:                         $r->print('<br />'.
                   2266:       &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.',
                   2267:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2268:                         next;
                   2269:                     }
1.26      matthew  2270:                     # determine student id number
1.25      matthew  2271:                     my $id='';
                   2272:                     if (defined($fields{'id'})) {
                   2273:                         if (defined($entries{$fields{'id'}})) {
                   2274:                             $id=$entries{$fields{'id'}};
                   2275:                         }
                   2276:                         $id=~tr/A-Z/a-z/;
                   2277:                     }
1.73      www      2278:                     # determine email address
                   2279:                     my $email='';
                   2280:                     if (defined($fields{'email'})) {
                   2281:                         if (defined($entries{$fields{'email'}})) {
                   2282:                             $email=$entries{$fields{'email'}};
                   2283:                             unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
                   2284:                         }
                   2285:                     }
1.26      matthew  2286:                     # determine student password
1.25      matthew  2287:                     my $password='';
                   2288:                     if ($genpwd) { 
                   2289:                         $password=$genpwd; 
                   2290:                     } else {
                   2291:                         if (defined($fields{'ipwd'})) {
                   2292:                             if ($entries{$fields{'ipwd'}}) {
                   2293:                                 $password=$entries{$fields{'ipwd'}};
                   2294:                             }
                   2295:                         }
                   2296:                     }
1.56      matthew  2297:                     # Clean up whitespace
                   2298:                     foreach (\$domain,\$username,\$id,\$fname,\$mname,
                   2299:                              \$lname,\$gen,\$sec) {
                   2300:                         $$_ =~ s/(\s+$|^\s+)//g;
                   2301:                     }
1.127     albertel 2302:                     if ($password || $env{'form.login'} eq 'loc') {
1.33      matthew  2303:                         &modifystudent($domain,$username,$cid,$sec,
                   2304:                                        $desiredhost);
1.25      matthew  2305:                         my $reply=&Apache::lonnet::modifystudent
                   2306:                             ($domain,$username,$id,$amode,$password,
                   2307:                              $fname,$mname,$lname,$gen,$sec,$enddate,
1.127     albertel 2308:                              $startdate,$env{'form.forceid'},$desiredhost,
1.73      www      2309:                              $email);
1.26      matthew  2310:                         if ($reply ne 'ok') {
1.72      matthew  2311:                             $reply =~ s/^error://;
1.88      matthew  2312:                             $r->print('<br />'.
                   2313:                 &mt('<b>[_1]</b>:  Unable to enroll: [_2]',$username,$reply));
1.10      www      2314:          		} else {
1.7       www      2315:                             $count++; $flushc++;
                   2316:                             $student{$username}=1;
1.6       www      2317:                             $r->print('. ');
1.7       www      2318:                             if ($flushc>15) {
                   2319: 				$r->rflush;
                   2320:                                 $flushc=0;
                   2321:                             }
1.6       www      2322:                         }
1.25      matthew  2323:                     } else {
1.88      matthew  2324:                         $r->print('<br />'.
                   2325:       &mt('<b>[_1]</b>: Unable to enroll.  No password specified.',$username)
                   2326:                                   );
1.25      matthew  2327:                     }
                   2328:                 }
1.26      matthew  2329:             }
                   2330:         } # end of foreach (@studentdata)
1.88      matthew  2331:         $r->print("</p>\n<p>\n".&mt('Processed [_1] student(s).',$count).
                   2332:                   "</p>\n");
                   2333:         $r->print("<p>\n".
                   2334:                   &mt('If active, the new role will be available when the '.
                   2335:                   'students next log in to LON-CAPA.')."</p>\n");
1.26      matthew  2336:         #####################################
                   2337:         #           Drop students           #
                   2338:         #####################################
1.127     albertel 2339:         if ($env{'form.fullup'} eq 'yes') {
1.88      matthew  2340:             $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");
1.26      matthew  2341:             #  Get current classlist
1.56      matthew  2342:             my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   2343:             if (! defined($classlist)) {
1.88      matthew  2344:                 $r->print(&mt('There are no students currently enrolled.').
                   2345:                           "\n");
1.56      matthew  2346:             } else {
                   2347:                 # Remove the students we just added from the list of students.
1.25      matthew  2348:                 foreach (@studentdata) {
                   2349:                     my %entries=&Apache::loncommon::record_sep($_);
                   2350:                     unless (($entries{$fields{'username'}} eq '') ||
                   2351:                             (!defined($entries{$fields{'username'}}))) {
1.56      matthew  2352:                         delete($classlist->{$entries{$fields{'username'}}.
1.26      matthew  2353:                                                 ':'.$domain});
1.25      matthew  2354:                     }
                   2355:                 }
1.56      matthew  2356:                 # Print out list of dropped students.
                   2357:                 &show_drop_list($r,$classlist,$keylist,'nosort');
1.25      matthew  2358:             }
                   2359:         }
1.26      matthew  2360:     } # end of unless
1.10      www      2361: }
                   2362: 
1.11      www      2363: # ================================================================== Phase four
                   2364: sub drop_student_list {
                   2365:     my $r=shift;
                   2366:     my $count=0;
1.128     albertel 2367:     my @droplist = &Apache::loncommon::get_env_multiple('form.droplist');
1.35      matthew  2368:     foreach (@droplist) {
1.26      matthew  2369:         my ($uname,$udom)=split(/\:/,$_);
1.56      matthew  2370:         # drop student
1.127     albertel 2371:         my $result = &modifystudent($udom,$uname,$env{'request.course.id'});
1.37      matthew  2372:         if ($result eq 'ok' || $result eq 'ok:') {
1.88      matthew  2373:             $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>');
1.59      matthew  2374:             $count++;
1.35      matthew  2375:         } else {
1.88      matthew  2376:             $r->print(
                   2377:           &mt('Error dropping [_1]:[_2]',$uname.'@'.$udom,$result).
1.35      matthew  2378:                       '<br />');
                   2379:         }
1.20      harris41 2380:     }
1.88      matthew  2381:     $r->print('<p><b>'.&mt('Dropped [_1] student(s).',$count).'</b></p>');
                   2382:     $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count);
1.11      www      2383: }
                   2384: 
1.142     raeburn  2385: sub section_check_js {
                   2386:     my $groupslist;
1.143     raeburn  2387:     my %curr_groups = &Apache::longroup::coursegroups();
1.142     raeburn  2388:     if (%curr_groups) {
                   2389:         $groupslist = join('","',sort(keys(%curr_groups)));
                   2390:     }
                   2391:     return <<"END";
                   2392: function validate(caller) {
                   2393:     var groups = new Array("$groupslist");
                   2394:     var secname = caller.value;
                   2395:     if ((secname == 'all') || (secname == 'none')) {
                   2396:         alert("'"+secname+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
                   2397:         return 'error';
                   2398:     }
                   2399:     if (secname != '') {
                   2400:         for (var k=0; k<groups.length; k++) {
                   2401:             if (secname == groups[k]) {
                   2402:                 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.");
                   2403:                 return 'error';
                   2404:             }
                   2405:         }
                   2406:     }
                   2407:     return 'ok';
                   2408: }
                   2409: END
                   2410: }
                   2411: 
1.50      matthew  2412: ###################################################################
                   2413: ###################################################################
                   2414: 
                   2415: =pod
                   2416: 
                   2417: =item &handler
                   2418: 
                   2419: The typical handler you see in all these modules.  Takes $r, the
                   2420: http request, as an argument.  
                   2421: 
                   2422: The response to the request is governed by two form variables
                   2423: 
                   2424:  form.action      form.state     response
                   2425:  ---------------------------------------------------
                   2426:  undefined        undefined      print main menu
                   2427:  upload           undefined      print courselist upload menu
                   2428:  upload           got_file       deal with uploaded file,
                   2429:                                  print the upload managing menu
                   2430:  upload           enrolling      enroll students based on upload
                   2431:  drop             undefined      print the classlist ready to drop
                   2432:  drop             done           drop the selected students
1.74      matthew  2433:  enrollstudent    undefined      print student username domain form
                   2434:  enrollstudent    gotusername    print single student enroll menu
1.50      matthew  2435:  enrollstudent    enrolling      enroll student
                   2436:  classlist        undefined      print html classlist
                   2437:  classlist        csv            print csv classlist
                   2438:  modifystudent    undefined      print classlist to select student to modify
                   2439:  modifystudent    selected       print modify student menu
                   2440:  modifystudent    done           make modifications to student record
                   2441: 
                   2442: =cut
                   2443: 
                   2444: ###################################################################
                   2445: ###################################################################
1.10      www      2446: sub handler {
1.26      matthew  2447:     my $r=shift;
                   2448:     if ($r->header_only) {
1.86      www      2449:         &Apache::loncommon::content_type($r,'text/html');
1.26      matthew  2450:         $r->send_http_header;
                   2451:         return OK;
                   2452:     }
1.48      matthew  2453:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.50      matthew  2454:                                             ['action','state']);
1.102     matthew  2455: 
                   2456:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   2457:     &Apache::lonhtmlcommon::add_breadcrumb
                   2458:         ({href=>"/adm/dropadd",
                   2459:           text=>"Enrollment Manager",
                   2460:           faq=>9,bug=>'Instructor Interface',});
1.26      matthew  2461:     #  Needs to be in a course
1.127     albertel 2462:     if (! ($env{'request.course.fn'})) {
1.121     matthew  2463:         # Not in a course
1.127     albertel 2464:         $env{'user.error.msg'}=
1.132     raeburn  2465:             "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ".
                   2466:                                   "or drop or add students";
1.50      matthew  2467:         return HTTP_NOT_ACCEPTABLE; 
                   2468:     }
                   2469:     #
1.121     matthew  2470:     my $view_permission = 
1.127     albertel 2471:         &Apache::lonnet::allowed('vcl',$env{'request.course.id'});
1.121     matthew  2472:     my $enrl_permission = 
1.127     albertel 2473:         &Apache::lonnet::allowed('cst',$env{'request.course.id'});
1.132     raeburn  2474: 
                   2475:     my $grp_view_permission =
                   2476:         &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
                   2477:     my $grp_manage_permission =
                   2478:         &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
                   2479: 
                   2480: 
                   2481:     if (! $grp_view_permission && ! $grp_manage_permission && 
                   2482:                                   ! $view_permission && ! $enrl_permission) {
1.127     albertel 2483:         $env{'user.error.msg'}=
1.132     raeburn  2484:      "/adm/coursegroups:cst:0:0:Cannot manage or view course groups, ".
                   2485:                                  "or drop or add students";
                   2486:         return HTTP_NOT_ACCEPTABLE;
1.121     matthew  2487:     }
1.132     raeburn  2488: 
1.121     matthew  2489:     #
1.50      matthew  2490:     # Only output the header information if they did not request csv format
                   2491:     #
1.103     matthew  2492:     # Start page
                   2493:     &Apache::loncommon::content_type($r,'text/html');
                   2494:     $r->send_http_header;
                   2495:     $r->print(&header());
1.50      matthew  2496:     #
                   2497:     # Main switch on form.action and form.state, as appropriate
1.127     albertel 2498:     if (! exists($env{'form.action'})) {
1.141     albertel 2499:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.132     raeburn  2500:         &print_main_menu($r,$enrl_permission,$view_permission,$grp_manage_permission,
                   2501:                          $grp_view_permission);
1.127     albertel 2502:     } elsif ($env{'form.action'} eq 'upload' && $enrl_permission) {
1.102     matthew  2503:         &Apache::lonhtmlcommon::add_breadcrumb
                   2504:             ({href=>'/adm/dropadd?action=upload&state=',
1.106     matthew  2505:               text=>"Upload Classlist"});
1.141     albertel 2506:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Upload Classlist',
                   2507: 						      'Course_Create_Class_List'));
1.127     albertel 2508:         if (! exists($env{'form.state'})) {
1.50      matthew  2509:             &print_first_courselist_upload_form($r);            
1.127     albertel 2510:         } elsif ($env{'form.state'} eq 'got_file') {
1.50      matthew  2511:             &print_upload_manager_form($r);
1.127     albertel 2512:         } elsif ($env{'form.state'} eq 'enrolling') {
                   2513:             if ($env{'form.datatoken'}) {
1.26      matthew  2514:                 &upfile_drop_add($r);
1.50      matthew  2515:             } else {
                   2516:                 # Hmmm, this is an error
1.26      matthew  2517:             }
1.50      matthew  2518:         } else {
                   2519:             &print_first_courselist_upload_form($r);            
1.26      matthew  2520:         }
1.127     albertel 2521:     } elsif ($env{'form.action'} eq 'drop' && $enrl_permission) {
1.102     matthew  2522:         &Apache::lonhtmlcommon::add_breadcrumb
                   2523:             ({href=>'/adm/dropadd?action=drop',
1.106     matthew  2524:               text=>"Drop Students"});
1.141     albertel 2525:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students',
                   2526: 						      'Course_Drop_Student'));
1.127     albertel 2527:         if (! exists($env{'form.state'})) {
1.51      matthew  2528:             &print_drop_menu($r);
1.127     albertel 2529:         } elsif ($env{'form.state'} eq 'done') {
1.26      matthew  2530:             &drop_student_list($r);
1.50      matthew  2531:         } else {
1.55      matthew  2532:             &print_drop_menu($r);
1.26      matthew  2533:         }
1.127     albertel 2534:     } elsif ($env{'form.action'} eq 'enrollstudent' && $enrl_permission) {
1.102     matthew  2535:         &Apache::lonhtmlcommon::add_breadcrumb
                   2536:             ({href=>'/adm/dropadd?action=enrollstudent',
1.106     matthew  2537:               text=>"Enroll Student"});
1.141     albertel 2538:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   2539: 						      'Course_Add_Student'));
1.127     albertel 2540:         if (! exists($env{'form.state'})) {
1.74      matthew  2541:             &get_student_username_domain_form($r);
1.127     albertel 2542:         } elsif ($env{'form.state'} eq 'gotusername') {
1.50      matthew  2543:             &print_enroll_single_student_form($r);
1.127     albertel 2544:         } elsif ($env{'form.state'} eq 'enrolling') {
1.26      matthew  2545:             &enroll_single_student($r);
1.50      matthew  2546:         } else {
1.74      matthew  2547:             &get_student_username_domain_form($r);
1.26      matthew  2548:         }
1.127     albertel 2549:     } elsif ($env{'form.action'} eq 'classlist' && $view_permission) {
1.102     matthew  2550:         &Apache::lonhtmlcommon::add_breadcrumb
                   2551:             ({href=>'/adm/dropadd?action=classlist',
1.106     matthew  2552:               text=>"View Classlist"});
1.141     albertel 2553:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('View Classlist',
                   2554: 						      'Course_View_Class_List'));
1.127     albertel 2555:         if (! exists($env{'form.state'})) {
1.103     matthew  2556:             &print_html_classlist($r,undef);
1.127     albertel 2557:         } elsif ($env{'form.state'} eq 'csv') {
1.103     matthew  2558:             &print_html_classlist($r,'csv');
1.127     albertel 2559:         } elsif ($env{'form.state'} eq 'excel') {
1.103     matthew  2560:             &print_html_classlist($r,'excel');
1.50      matthew  2561:         } else {
1.103     matthew  2562:             &print_html_classlist($r,undef);
1.50      matthew  2563:         }
1.127     albertel 2564:     } elsif ($env{'form.action'} eq 'modifystudent' && $enrl_permission) {
1.102     matthew  2565:         &Apache::lonhtmlcommon::add_breadcrumb
                   2566:             ({href=>'/adm/dropadd?action=modifystudent',
1.106     matthew  2567:               text=>"Modify Student Data"});
1.141     albertel 2568:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Modify Student Data',
                   2569: 						      'Course_Modify_Student_Data'));
1.127     albertel 2570:         if (! exists($env{'form.state'})) {
1.50      matthew  2571:             &print_html_classlist($r);
1.127     albertel 2572:         } elsif ($env{'form.state'} eq 'selected') {
1.50      matthew  2573:             &print_modify_student_form($r);
1.127     albertel 2574:         } elsif ($env{'form.state'} eq 'done') {
1.50      matthew  2575:             &modify_single_student($r);
                   2576:         } else {
                   2577:             &print_html_classlist($r);
                   2578:         }        
                   2579:     } else {
                   2580:         # We should not end up here, but I guess it is possible
                   2581:         &Apache::lonnet::logthis("Undetermined state in londropadd.pm.  ".
1.127     albertel 2582:                                  "form.action = ".$env{'form.action'}.
1.50      matthew  2583:                                  "Someone should fix this.");
1.141     albertel 2584:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.121     matthew  2585:         &print_main_menu($r,$enrl_permission,$view_permission);
1.50      matthew  2586:     }
                   2587:     #
                   2588:     # Finish up
1.138     albertel 2589:     $r->print('</form>'.&Apache::loncommon::end_page());
1.26      matthew  2590:     return OK;
1.1       www      2591: }
                   2592: 
1.50      matthew  2593: ###################################################################
                   2594: ###################################################################
                   2595: 
1.1       www      2596: 1;
                   2597: __END__
1.50      matthew  2598: 
1.1       www      2599: 

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