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

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

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