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

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

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