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

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

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