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

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

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