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

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

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