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

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

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