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

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

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