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

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to drop and add students in courses 
                      3: #
1.173   ! raeburn     4: # $Id: londropadd.pm,v 1.172 2007/10/11 02:16:25 albertel Exp $
1.17      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.1       www        28: #
1.50      matthew    29: ###############################################################
1.82      www        30: ##############################################################
1.1       www        31: 
                     32: package Apache::londropadd;
                     33: 
                     34: use strict;
1.127     albertel   35: use Apache::lonnet;
1.24      albertel   36: use Apache::loncommon();
1.50      matthew    37: use Apache::lonhtmlcommon();
1.1       www        38: use Apache::Constants qw(:common :http REDIRECT);
1.60      matthew    39: use Spreadsheet::WriteExcel;
1.110     matthew    40: use Apache::lonstathelpers();
1.86      www        41: use Apache::lonlocal;
1.143     raeburn    42: use Apache::longroup;
1.152     albertel   43: use LONCAPA();
1.1       www        44: 
1.50      matthew    45: ###############################################################
                     46: ###############################################################
1.10      www        47: sub header {
1.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.173   ! raeburn   426:         $section_checks = &Apache::lonuserutils::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.
1.173   ! raeburn   762:     my ($startdate,$enddate) = &Apache::lonuserutils::get_dates_from_form();
1.127     albertel  763:     if ($env{'form.makedatesdefault'}) {
1.173   ! raeburn   764:         $r->print(&Apache::lonuserutils::make_dates_default($startdate,
        !           765:                                                             $enddate));
1.68      matthew   766:     }
                    767: 
1.94      sakharuk  768:     $r->print('<h3>'.&mt('Enrolling Student').'</h3>');
1.162     albertel  769:     $r->print('<p>'.&mt('Enrolling [_1] : [_2]',$env{'form.cuname'},
                    770: 			$env{'form.lcdomain'}).'</p>');
1.150     albertel  771:     if (($env{'form.cuname'})
                    772: 	&& ($env{'form.cuname'} 
                    773: 	    eq &LONCAPA::clean_username($env{'form.cuname'}))
                    774: 	&& ($env{'form.lcdomain'})
                    775: 	&& ($env{'form.lcdomain'}
                    776: 	    eq &LONCAPA::clean_domain($env{'form.lcdomain'}))) {
1.31      matthew   777:         # Deal with home server selection
1.127     albertel  778:         my $domain=$env{'form.lcdomain'};
                    779:         my $desiredhost = $env{'form.lcserver'};
1.31      matthew   780:         if (lc($desiredhost) eq 'default') {
                    781:             $desiredhost = undef;
                    782:         } else {
1.157     albertel  783:             my %home_servers =&Apache::lonnet::get_servers($domain,'library');
1.31      matthew   784:             if (! exists($home_servers{$desiredhost})) {
1.94      sakharuk  785:                 $r->print('<font color="#ff0000">'.&mt('Error').':</font>'.
                    786:                           &mt('Invalid home server specified'));
1.31      matthew   787:                 return;
                    788:             }
                    789:         }
1.94      sakharuk  790:         $r->print(" ".&mt('with server')." $desiredhost :") if (defined($desiredhost));
1.31      matthew   791:         # End of home server selection logic
1.12      www       792: 	my $amode='';
                    793:         my $genpwd='';
1.127     albertel  794:         if ($env{'form.login'} eq 'krb') {
1.47      albertel  795:            $amode='krb';
1.127     albertel  796: 	   $amode.=$env{'form.krbver'};
                    797:            $genpwd=$env{'form.krbarg'};
                    798:         } elsif ($env{'form.login'} eq 'int') {
1.26      matthew   799:            $amode='internal';
1.127     albertel  800:            $genpwd=$env{'form.intarg'};
                    801:         }  elsif ($env{'form.login'} eq 'loc') {
1.15      albertel  802: 	    $amode='localauth';
1.127     albertel  803: 	    $genpwd=$env{'form.locarg'};
1.15      albertel  804: 	    if (!$genpwd) { $genpwd=" "; }
                    805: 	}
1.127     albertel  806:         my $home = &Apache::lonnet::homeserver($env{'form.cuname'},
                    807:                                                    $env{'form.lcdomain'});
1.34      matthew   808:         if ((($amode) && ($genpwd)) || ($home ne 'no_host')) {
1.55      matthew   809:             # Clean out any old roles the student has in this class.
1.173   ! raeburn   810:             &Apache::lonuserutils::modifystudent($env{'form.lcdomain'},$env{'form.cuname'},
1.127     albertel  811:                            $env{'request.course.id'},$env{'form.csec'},
1.33      matthew   812:                             $desiredhost);
1.55      matthew   813:             my $login_result = &Apache::lonnet::modifystudent
1.127     albertel  814:                 ($env{'form.lcdomain'},$env{'form.cuname'},
                    815:                  $env{'form.cstid'},$amode,$genpwd,
                    816:                  $env{'form.cfirst'},$env{'form.cmiddle'},
                    817:                  $env{'form.clast'},$env{'form.cgen'},
                    818:                  $env{'form.csec'},$enddate,
                    819:                  $startdate,$env{'form.forceid'},
                    820:                  $desiredhost,$env{'form.emailaddress'});
1.55      matthew   821:             if ($login_result =~ /^ok/) {
                    822:                 $r->print($login_result);
1.94      sakharuk  823:                 $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   824:             } else {
1.94      sakharuk  825:                 $r->print(&mt('unable to enroll').": ".$login_result);
1.55      matthew   826:             }
1.12      www       827: 	} else {
1.94      sakharuk  828:             $r->print('<p><font color="#ff0000">'.&mt('ERROR').'</font>&nbsp;');
1.79      matthew   829:             if ($amode =~ /^krb/) {
1.94      sakharuk  830:                 $r->print(&mt('Missing Kerberos domain information.').'  ');
1.79      matthew   831:             } else {
1.94      sakharuk  832:                 $r->print(&mt('Invalid login mode or password.').'  ');
1.79      matthew   833:             }
1.127     albertel  834:             $r->print('<b>'.&mt('Unable to enroll').' '.$env{'form.cuname'}.'.</b></p>');
1.79      matthew   835:         }
1.12      www       836:     } else {
1.94      sakharuk  837:         $r->print(&mt('Invalid username or domain'));
1.26      matthew   838:     }    
1.155     www       839:     $r->print("<p><a href='/adm/dropadd?action=enrollstudent'>".&mt("Enroll another student")."</a></p>");
1.166     raeburn   840:     if (ref($srcharray) eq 'ARRAY') {
                    841:         foreach my $item (@{$srcharray},'ccuname','ccdomain') {
                    842:             $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n");
                    843:         }
                    844:     }
                    845:     foreach my $item ('sortby','seluname','seludom') {
                    846:         if (exists($env{'form.'.$item})) {
                    847:             $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n");
                    848:         }
                    849:     }
                    850:     $r->print('<input type="hidden" name="phase" value="get_user_info" />'."\n".
                    851:               '<input type="hidden" name="currstate" value="" />'."\n".
                    852:               '<input type="hidden" name="prevphase" value="" />'."\n".
                    853:               '<input type="hidden" name="action" value="enrollstudent" />'."\n".
                    854:               '<input type="hidden" name="state" value="gotusername" />');
1.12      www       855: }
                    856: 
1.68      matthew   857: sub setup_date_selectors {
1.91      raeburn   858:     my ($starttime,$endtime,$mode) = @_;
1.68      matthew   859:     if (! defined($starttime)) {
                    860:         $starttime = time;
1.114     raeburn   861:         unless ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
1.127     albertel  862:             if (exists($env{'course.'.$env{'request.course.id'}.
1.68      matthew   863:                             '.default_enrollment_start_date'})) {
1.127     albertel  864:                 $starttime = $env{'course.'.$env{'request.course.id'}.
1.68      matthew   865:                                   '.default_enrollment_start_date'};
1.91      raeburn   866:             }
1.68      matthew   867:         }
                    868:     }
                    869:     if (! defined($endtime)) {
                    870:         $endtime = time+(6*30*24*60*60); # 6 months from now, approx
1.91      raeburn   871:         unless ($mode eq 'createcourse') {
1.127     albertel  872:             if (exists($env{'course.'.$env{'request.course.id'}.
1.68      matthew   873:                             '.default_enrollment_end_date'})) {
1.127     albertel  874:                 $endtime = $env{'course.'.$env{'request.course.id'}.
1.68      matthew   875:                                 '.default_enrollment_end_date'};
1.91      raeburn   876:             }
1.68      matthew   877:         }
                    878:     }
                    879:     my $startdateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    880:                                                             'startdate',
                    881:                                                             $starttime);
                    882:     my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform',
                    883:                                                           'enddate',
                    884:                                                           $endtime);
1.114     raeburn   885:     if ($mode eq 'create_enrolldates') {
                    886:         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    887:                                                             'startenroll',
                    888:                                                             $starttime);
                    889:         $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
                    890:                                                           'endenroll',
                    891:                                                           $endtime);
                    892:     }
                    893:     if ($mode eq 'create_defaultdates') {
1.91      raeburn   894:         $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
1.114     raeburn   895:                                                             'startaccess',
1.91      raeburn   896:                                                             $starttime);
                    897:         $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
1.114     raeburn   898:                                                           'endaccess',
1.91      raeburn   899:                                                           $endtime);
                    900:     }
1.68      matthew   901:     return ($startdateform,$enddateform);
                    902: }
                    903: 
                    904: sub get_dates_from_form {
                    905:     my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
                    906:     my $enddate   = &Apache::lonhtmlcommon::get_date_from_form('enddate');
1.127     albertel  907:     if ($env{'form.no_end_date'}) {
1.68      matthew   908:         $enddate = 0;
                    909:     }
                    910:     return ($startdate,$enddate);
                    911: }
                    912: 
                    913: sub date_setting_table {
1.91      raeburn   914:     my ($starttime,$endtime,$mode) = @_;
                    915:     my ($startform,$endform)=&setup_date_selectors($starttime,$endtime,$mode);
1.68      matthew   916:     my $dateDefault = '<nobr>'.
1.131     albertel  917:         '<label><input type="checkbox" name="makedatesdefault" /> '.
1.160     albertel  918:         &mt('make these dates the default for future enrollment').
                    919: 	'</label></nobr>';
1.114     raeburn   920:     if ($mode eq 'create_enrolldates' || $mode eq 'create_defaultdates') {
1.91      raeburn   921:         $dateDefault = '&nbsp;';
                    922:     }
1.131     albertel  923:     my $perpetual = '<nobr><label><input type="checkbox" name="no_end_date"';
1.68      matthew   924:     if (defined($endtime) && $endtime == 0) {
                    925:         $perpetual .= ' checked';
                    926:     }
1.131     albertel  927:     $perpetual.= ' /> '.&mt('no ending date').'</label></nobr>';
1.114     raeburn   928:     if ($mode eq 'create_enrolldates') {
                    929:         $perpetual = '&nbsp;';
                    930:     }
1.68      matthew   931:     my $result = '';
                    932:     $result .= "<table>\n";
1.94      sakharuk  933:     $result .= '<tr><td align="right">'.&mt('Starting Date').'</td>'.
1.68      matthew   934:         '<td>'.$startform.'</td>'.
                    935:         '<td>'.$dateDefault.'</td>'."</tr>\n";
1.94      sakharuk  936:     $result .= '<tr><td align="right">'.&mt('Ending Date').'</td>'.
1.68      matthew   937:         '<td>'.$endform.'</td>'.
                    938:         '<td>'.$perpetual.'</td>'."</tr>\n";
                    939:     $result .= "</table>\n";
                    940:     return $result;
                    941: }
                    942: 
                    943: sub make_dates_default {
                    944:     my ($startdate,$enddate) = @_;
                    945:     my $result = '';
1.127     albertel  946:     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                    947:     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
1.68      matthew   948:     my $put_result = &Apache::lonnet::put('environment',
                    949:             {'default_enrollment_start_date'=>$startdate,
                    950:              'default_enrollment_end_date'  =>$enddate},$dom,$crs);
                    951:     if ($put_result eq 'ok') {
                    952:         $result .= "Set default start and end dates for course<br />";
1.69      matthew   953:         #
                    954:         # Refresh the course environment
1.140     albertel  955:         &Apache::lonnet::coursedescription($env{'request.course.id'},
                    956: 					   {'freshen_cache' => 1});
1.68      matthew   957:     } else {
1.94      sakharuk  958:         $result .= &mt('Unable to set default dates for course').":".$put_result.
1.68      matthew   959:             '<br />';
                    960:     }
                    961:     return $result;
                    962: }
                    963: 
1.74      matthew   964: ##
                    965: ## Single student enrollment routines (some of them)
                    966: ##
                    967: sub get_student_username_domain_form {
1.166     raeburn   968:     my ($r,$elements,$response,$srch,$forcenewuser) =  @_;
                    969:     my $loaditems = {
                    970:             'onload' => "javascript:setFormElements(document.studentform)",
                    971:                      };
                    972:     $r->print(&header(undef,$loaditems));
                    973:     &Apache::lonhtmlcommon::add_breadcrumb
                    974:         ({href=>"javascript:backPage(document.studentform,'','')",
                    975:           text=>"Single user search"});
                    976:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                    977:                                                   'Course_Add_Student'));
                    978:     my $defdom=$env{'request.role.domain'};
                    979: 
                    980:     my $jscript = &Apache::loncommon::studentbrowser_javascript()."\n".
                    981:         '<script type="text/javascript">'."\n".
                    982:         &Apache::lonhtmlcommon::set_form_elements($elements->{'studentform'}).
                    983:         '</script>'."\n";
                    984: 
1.94      sakharuk  985:     my %lt=&Apache::lonlocal::texthash(
                    986: 		    'eos'  => "Enroll One Student",
                    987: 		    'usr'  => "Username",
                    988:                     'dom'  => "Domain",
                    989:                     'been' => "Begin Enrollment",
                    990: 				       );
1.74      matthew   991:     $r->print(<<END);
1.166     raeburn   992: $jscript
1.94      sakharuk  993: <h3>$lt{'eos'}</h3>
1.74      matthew   994: END
1.169     raeburn   995:     $r->print($response);
1.166     raeburn   996:     $r->print(&single_user_entry_form($defdom,$srch,$forcenewuser));
1.74      matthew   997:     return;
                    998: }
                    999: 
1.166     raeburn  1000: sub single_user_entry_form {
                   1001:     my ($dom,$srch,$forcenewuser) = @_;
                   1002:     my $userpicker =
                   1003:        &Apache::loncommon::user_picker($dom,$srch,$forcenewuser,
                   1004:                                        'document.studentform');
                   1005:     my $srchbutton = &mt('Search');
                   1006:     my $output = <<"ENDDOCUMENT";
                   1007: <input type="hidden" name="action" value="enrollstudent" />
                   1008: <input type="hidden" name="state" value="gotusername" />
                   1009: <input type="hidden" name="phase" value="get_user_info" />
                   1010: $userpicker
                   1011: <input name="userrole" type="button" value="$srchbutton" onclick="javascript:validateEntry(document.studentform)" />
                   1012: ENDDOCUMENT
                   1013:     return $output;
                   1014: }
                   1015: 
1.50      matthew  1016: sub print_enroll_single_student_form {
1.166     raeburn  1017:     my ($r,$jscript,$ccuname,$ccdomain,$srch) = @_;
                   1018:     $r->print(&header($jscript));
                   1019:     &Apache::lonhtmlcommon::add_breadcrumb
                   1020:         ({href=>"javascript:backPage(document.studentform,'','')",
                   1021:           text=>"Single user search"});
                   1022:     if ($env{'form.phase'} eq 'userpicked') {
                   1023:         &Apache::lonhtmlcommon::add_breadcrumb
                   1024:      ({href=>"javascript:backPage(document.studentform,'get_user_info','select')",
                   1025:        text=>"Select user",});
                   1026:     }
                   1027:     &Apache::lonhtmlcommon::add_breadcrumb
                   1028:       ({href=>"javascript:backPage(document.studentform,'$env{'form.phase'}','modify')",
                   1029:         text=>"Set enrollment",});
                   1030:     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   1031:                                                   'Course_Add_Student'));
1.94      sakharuk 1032:     $r->print("<h3>".&mt('Enroll One Student')."</h3>");
1.74      matthew  1033:     #
1.166     raeburn  1034:     my $home = &Apache::lonnet::homeserver($ccuname,$ccdomain);
1.74      matthew  1035:     # $new_user flags whether we are creating a new user or using an old one
                   1036:     my $new_user = 1;
                   1037:     if ($home ne 'no_host') {
                   1038:         $new_user = 0;
                   1039:     }
                   1040:     #
                   1041:     my $user_data_html = '';
                   1042:     my $javascript_validations = '';
                   1043:     if ($new_user) {
1.166     raeburn  1044:         my $usertoadd;
                   1045:         my $instsrch = {
                   1046:                          srchin => 'instd',
                   1047:                          srchby => 'uname',
                   1048:                          srchtype => 'exact',
                   1049:                          srchterm => $ccuname,
                   1050:                          srchdomain => $ccdomain,
                   1051:                        };
                   1052:         if (($instsrch->{'srchterm'} ne '') && ($instsrch->{'srchdomain'} ne '')) {
                   1053:             $usertoadd = $instsrch->{'srchterm'}.':'.$instsrch->{'srchdomain'};
                   1054:         }
                   1055:         my (%dirsrch_results,%inst_results);
                   1056:         if ($usertoadd) {
                   1057:             if (&Apache::loncreateuser::directorysrch_check($instsrch) eq 'ok') {
                   1058:                 %dirsrch_results = &Apache::lonnet::inst_directory_query($instsrch);
                   1059:                 if (ref($dirsrch_results{$usertoadd}) eq 'HASH') {
                   1060:                     %inst_results = %{$dirsrch_results{$usertoadd}};
                   1061:                 }
                   1062:             }
                   1063:         }
                   1064: 
1.127     albertel 1065:         my $defdom=$env{'course.'.$env{'request.course.id'}.'.domain'};
1.74      matthew  1066:         # Set up authentication forms
                   1067:         my ($krbdef,$krbdefdom) =
1.166     raeburn  1068:             &Apache::loncommon::get_kerberos_defaults($ccdomain);
1.171     raeburn  1069:         $javascript_validations = 
1.173   ! raeburn  1070:             &Apache::lonuserutils::javascript_validations('auth',$krbdefdom,
        !          1071:                                                       undef,undef,$ccdomain);
1.74      matthew  1072:         my %param = ( formname => 'document.studentform',
                   1073:                       kerb_def_dom => $krbdefdom,
                   1074:                       kerb_def_auth => $krbdef
                   1075:                       );
                   1076:         my $krbform = &Apache::loncommon::authform_kerberos(%param);
                   1077:         my $intform = &Apache::loncommon::authform_internal(%param);
                   1078:         my $locform = &Apache::loncommon::authform_local(%param);
                   1079:         #
                   1080:         # Set up domain selection form
                   1081:         my $homeserver_form = '';
1.166     raeburn  1082:         my %servers = &Apache::lonnet::get_servers($ccdomain,'library');
1.74      matthew  1083:         $homeserver_form = '<select name="lcserver" size="1">'."\n".
                   1084:             '<option value="default" selected>default</option>'."\n";
                   1085:         while (my ($servername,$serverdescription) = each (%servers)) {
                   1086:             $homeserver_form .= '<option value="'.$servername.'">'.
                   1087:                 $serverdescription."</option>\n";
                   1088:         }
                   1089:         $homeserver_form .= "</select>\n";
                   1090:         #
                   1091:         #
1.94      sakharuk 1092: 	my %lt=&Apache::lonlocal::texthash(
1.171     raeburn  1093: 		       'udf'  => "Personal Data",
1.94      sakharuk 1094:                        'fn'   => "First Name",
                   1095:                        'mn'   => "Middle Name",
                   1096:                        'ln'   => "Last Name",
                   1097:                        'gen'  => "Generation",
                   1098:                        'hs'   => "Home Server",
1.171     raeburn  1099:                        'pswd' => "Login Data",
1.94      sakharuk 1100: 		       'psam' => "Please select an authentication mechanism",
1.124     www      1101:                        'mail' => "Email Address"
1.94      sakharuk 1102: 					   );
1.130     www      1103: 	my $authhelp=&Apache::loncommon::help_open_topic('Auth_Options');
1.74      matthew  1104:         $user_data_html = <<END;
1.166     raeburn  1105: <h3>$lt{'udf'} $ccuname:$ccdomain</h3>
1.74      matthew  1106: <table>
1.159     www      1107: <tr><td class="LC_dropadd_labeltext"><label for="cfirst">$lt{'fn'}</label>:</td>
1.166     raeburn  1108:     <td><input type="text" name="cfirst" size="15" value="$inst_results{'firstname'}" /></td></tr>
1.159     www      1109: <tr><td class="LC_dropadd_labeltext"><label for="cmiddle">$lt{'mn'}</label>:</td>
1.166     raeburn  1110:     <td><input type="text" name="cmiddle" size="15" value="$inst_results{'middlename'}" /></td></tr>
1.159     www      1111: <tr><td class="LC_dropadd_labeltext"><label for="clast">$lt{'ln'}</label>:</td>
1.166     raeburn  1112:     <td><input type="text" name="clast" size="15" value="$inst_results{'lastname'}" /></td></tr>
1.159     www      1113: <tr><td class="LC_dropadd_labeltext"><label for="cgen">$lt{'gen'}</label>:</td>
1.166     raeburn  1114:     <td><input type="text" name="cgen" size="5" value="$inst_results{'generation'}" /> </td></tr>
1.159     www      1115: <tr><td class="LC_dropadd_labeltext"><label for="lcserver">$lt{'hs'}</label>:</td>
1.74      matthew  1116:     <td>$homeserver_form</td></tr>
1.159     www      1117: <tr><td class="LC_dropadd_labeltext"><label for="emailaddress">$lt{'mail'}</label>:</td>
1.166     raeburn  1118:     <td><input type="text" name="emailaddress" size="20" value="$inst_results{'permanentemail'}" /></td></tr>
1.74      matthew  1119: </table>
1.94      sakharuk 1120: <h3>$lt{'pswd'}</h3>
1.130     www      1121: $lt{'psam'}$authhelp
1.74      matthew  1122: <p>
                   1123: END
1.171     raeburn  1124:         if ($krbform ne '') {
                   1125:             $user_data_html .= $krbform.'<br />';
                   1126:         }
                   1127:         if ($intform ne '') {
                   1128:             $user_data_html .= $intform.'<br />';
                   1129:         }
                   1130:         if ($locform ne '') {
                   1131:             $user_data_html .= $locform.'<br />';
                   1132:         }
                   1133:         $user_data_html .= "\n</p>\n"
1.74      matthew  1134:     } else {
                   1135:         # User already exists.  Do not worry about authentication
1.166     raeburn  1136:         my %uenv = &Apache::lonnet::dump('environment',$ccdomain,$ccuname);
1.173   ! raeburn  1137:         $javascript_validations = &Apache::lonuserutils::javascript_validations('noauth');
1.94      sakharuk 1138: 	my %lt=&Apache::lonlocal::texthash(
                   1139: 		       'udf'  => "User Data for",
                   1140:                        'fn'   => "First Name",
                   1141:                        'mn'   => "Middle Name",
                   1142:                        'ln'   => "Last Name",
                   1143:                        'gen'  => "Generation",
1.124     www      1144:                        'mail' => "Email Address",
1.94      sakharuk 1145: 					   );
1.74      matthew  1146:         $user_data_html = <<END;
1.166     raeburn  1147: <h3>$lt{'udf'} $ccuname:$ccdomain</h3>
1.74      matthew  1148: <input type="hidden" name="lcserver" value="default" />
                   1149: <table>
1.159     www      1150: <tr><td class="LC_dropadd_labeltext"><label for="cfirst">$lt{'fn'}</label>:</td>
1.161     raeburn  1151:     <td><input type="text" name="cfirst" value="$uenv{'firstname'}" size="15" /></td></tr>
1.159     www      1152: <tr><td class="LC_dropadd_labeltext"><label for="cmiddle">$lt{'mn'}</label>:</td>
1.161     raeburn  1153:     <td><input type="text" name="cmiddle" value="$uenv{'middlename'}" size="15" /></td></tr>
1.159     www      1154: <tr><td class="LC_dropadd_labeltext"><label for="clast">$lt{'ln'}</label>:</td>
1.161     raeburn  1155:     <td><input type="text" name="clast" value="$uenv{'lastname'}" size="15" /></td></tr>
1.160     albertel 1156: <tr><td class="LC_dropadd_labeltext"><label for="cgen">$lt{'gen'}</label>:</td>
1.161     raeburn  1157:     <td><input type="text" name="cgen" value="$uenv{'generation'}" size="5"  /> </td></tr>
1.160     albertel 1158: <tr><td class="LC_dropadd_labeltext"><label for="emailaddress">$lt{'mail'}</label>:</td>
1.161     raeburn  1159:     <td><input type="text" name="emailaddress" value="$uenv{'permanentemail'}" size="20" /></td></tr>
1.74      matthew  1160: </table>
                   1161: END
                   1162:     }
1.173   ! raeburn  1163:     my $date_table = &Apache::lonuserutils::date_setting_table();
1.74      matthew  1164:         # Print it all out
1.94      sakharuk 1165:     my %lt=&Apache::lonlocal::texthash(
                   1166: 		   'cd'   => "Course Data",
1.142     raeburn  1167:                    'gs'   => "Section",
1.94      sakharuk 1168:                    'idsn' => "ID/Student Number",
                   1169:                    'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1170:                    'eas'  => "Enroll as student",
                   1171: 				       );
1.50      matthew  1172:     $r->print(<<END);
1.74      matthew  1173: <input type="hidden" name="action" value="enrollstudent" />
1.166     raeburn  1174: <input type="hidden" name="state"  value="gotusername" />
                   1175: <input type="hidden" name="cuname" value="$ccuname" />
                   1176: <input type="hidden" name="lcdomain" value="$ccdomain" />
1.28      matthew  1177: <script type="text/javascript" language="Javascript">
1.142     raeburn  1178: function verify(vf,sec_caller) {
1.12      www      1179:     var founduname=0;
                   1180:     var foundpwd=0;
                   1181:     var foundname=0;
                   1182:     var foundid=0;
                   1183:     var foundsec=0;
                   1184:     var tw;
1.26      matthew  1185:     if ((typeof(vf.cuname.value) !="undefined") && (vf.cuname.value!='') && 
1.31      matthew  1186: 	(typeof(vf.lcdomain.value)!="undefined") && (vf.lcdomain.value!='')) {
1.12      www      1187:         founduname=1;
                   1188:     }
1.14      harris41 1189:     if ((typeof(vf.cfirst.value)!="undefined") && (vf.cfirst.value!='') &&
1.26      matthew  1190: 	(typeof(vf.clast.value) !="undefined") && (vf.clast.value!='')) {
1.12      www      1191:         foundname=1;
                   1192:     }
1.14      harris41 1193:     if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) {
1.12      www      1194:         foundsec=1;
1.142     raeburn  1195:         if (validate(sec_caller) == "error") {
                   1196:             return;
                   1197:         }
1.12      www      1198:     }
1.14      harris41 1199:     if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) {
1.12      www      1200: 	foundid=1;
                   1201:     }
                   1202:     if (founduname==0) {
                   1203: 	alert('You need to specify at least the username and domain fields');
                   1204:         return;
                   1205:     }
1.24      albertel 1206:     verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
1.12      www      1207: }
                   1208: 
1.24      albertel 1209: $javascript_validations
1.12      www      1210: 
1.24      albertel 1211: function clearpwd(vf) {
                   1212:     //nothing else needs clearing
1.15      albertel 1213: }
                   1214: 
1.12      www      1215: </script>
1.11      www      1216: 
1.74      matthew  1217: $user_data_html
1.50      matthew  1218: 
1.94      sakharuk 1219: <h3>$lt{'cd'}</h3>
1.50      matthew  1220: 
1.159     www      1221: <p><label for="csec">$lt{'gs'}</label>: <input type="text" name="csec" size="5" />
1.160     albertel 1222: </p>
1.68      matthew  1223: $date_table
1.94      sakharuk 1224: <h3>$lt{'idsn'}</h3>
1.50      matthew  1225: <p>
1.160     albertel 1226: <label for="cstid">$lt{'idsn'}</label>: <input type="text" name="cstid" size="10" />
1.26      matthew  1227: </p><p>
1.131     albertel 1228: <label>
1.160     albertel 1229: <input type="checkbox" name="forceid" value="yes" /> 
1.94      sakharuk 1230: $lt{'disn'}
1.131     albertel 1231: </label>
1.50      matthew  1232: </p><p>
1.160     albertel 1233: <input type="button" onClick="verify(this.form,this.form.csec)" value="$lt{'eas'}" />
1.26      matthew  1234: </p>
1.50      matthew  1235: END
1.166     raeburn  1236:     $r->print('<input type="hidden" name="currstate" value="" />'."\n".
                   1237:               '<input type="hidden" name="phase" value="" />'."\n".
                   1238:               '<input type="hidden" name="prevphase" value="'.$env{'form.phase'}.'" />'."\n");
                   1239:     if (ref($srch) eq 'HASH') {
                   1240:         foreach my $item (sort(keys(%{$srch}))) {
                   1241:             $r->print('<input type="hidden" name="'.$item.'" value="'.$srch->{$item}.'" />'."\n");
                   1242:         }
                   1243:     }
                   1244:     foreach my $item ('sortby','seluname','seludom') {
                   1245:         if (exists($env{'form.'.$item})) {
                   1246:             $r->print('<input type="hidden" name="'.$item.'" value="'.$env{'form.'.$item}.'" />'."\n");
                   1247:         }
                   1248:     }
1.50      matthew  1249:     return;
1.10      www      1250: }
                   1251: 
                   1252: # ========================================================= Menu Phase Two Drop
1.51      matthew  1253: sub print_drop_menu {
1.10      www      1254:     my $r=shift;
1.92      sakharuk 1255:     $r->print("<h3>".&mt('Drop Students')."</h3>");
1.127     albertel 1256:     my $cid=$env{'request.course.id'};
1.56      matthew  1257:     my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
                   1258:     if (! defined($classlist)) {
1.94      sakharuk 1259:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.51      matthew  1260:         return;
1.25      matthew  1261:     }
1.51      matthew  1262:     # Print out the available choices
1.56      matthew  1263:     &show_drop_list($r,$classlist,$keylist);
1.51      matthew  1264:     return;
1.11      www      1265: }
                   1266: 
1.40      matthew  1267: # ============================================== view classlist
1.50      matthew  1268: sub print_html_classlist {
1.164     albertel 1269:     my ($r,$mode,$permission) = @_;
1.127     albertel 1270:     if (! exists($env{'form.sortby'})) {
                   1271:         $env{'form.sortby'} = 'username';
1.57      matthew  1272:     }
1.147     albertel 1273:     if ($env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.127     albertel 1274:         $env{'form.Status'} = 'Active';
1.57      matthew  1275:     }
                   1276:     my $status_select = &Apache::lonhtmlcommon::StatusOptions
1.127     albertel 1277:         ($env{'form.Status'});
1.150     albertel 1278:     my $cid =$env{'request.course.id'};
1.127     albertel 1279:     my $cdom=$env{'course.'.$cid.'.domain'};
                   1280:     my $cnum=$env{'course.'.$cid.'.num'};
1.103     matthew  1281:     #
                   1282:     # List course personnel
1.100     www      1283:     my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum);
1.110     matthew  1284:     #
1.127     albertel 1285:     if (! defined($env{'form.output'}) ||
                   1286:         $env{'form.output'} !~ /^(csv|excel|html)$/ ) {
                   1287:         $env{'form.output'} = 'html';
1.110     matthew  1288:     }
                   1289:     #
1.139     albertel 1290:     $r->print('<br />'.&Apache::loncommon::start_data_table());
1.110     matthew  1291:     foreach my $role (sort keys %coursepersonnel) {
                   1292:         next if ($role =~ /^\s*$/);
1.139     albertel 1293: 	$r->print(&Apache::loncommon::start_data_table_row().
                   1294: 		  '<td>'.$role.'</td><td>');
1.110     matthew  1295:         foreach my $user (split(',',$coursepersonnel{$role})) {
                   1296: 	    my ($puname,$pudom)=split(':',$user);
1.100     www      1297: 	    $r->print(' '.&Apache::loncommon::aboutmewrapper(
1.110     matthew  1298:                                     &Apache::loncommon::plainname($puname,
                   1299:                                                                   $pudom),
                   1300:                                                              $puname,$pudom));
1.100     www      1301: 	}
1.139     albertel 1302:         $r->print('</td>'.&Apache::loncommon::end_data_table_row());
1.100     www      1303:     }
1.139     albertel 1304:     $r->print(&Apache::loncommon::end_data_table());
1.103     matthew  1305:     #
                   1306:     # Interface output
                   1307:     $r->print('<input type="hidden" name="action" value="'.
1.127     albertel 1308:               $env{'form.action'}.'" />');
1.103     matthew  1309:     $r->print("<p>\n");
1.127     albertel 1310:     if ($env{'form.action'} ne 'modifystudent') {
1.103     matthew  1311: 	my %lt=&Apache::lonlocal::texthash('csv' => "CSV",
                   1312:                                            'excel' => "Excel",
                   1313:                                            'html'  => 'HTML');
1.110     matthew  1314:         my $output_selector = '<select size="1" name="output" >';
1.103     matthew  1315:         foreach my $outputformat ('html','csv','excel') {
                   1316:             my $option = '<option value="'.$outputformat.'" ';
1.127     albertel 1317:             if ($outputformat eq $env{'form.output'}) {
1.104     matthew  1318:                 $option .= 'selected ';
1.103     matthew  1319:             }
                   1320:             $option .='>'.$lt{$outputformat}.'</option>';
                   1321:             $output_selector .= "\n".$option;
                   1322:         }
                   1323:         $output_selector .= '</select>';
1.159     www      1324:         $r->print('<label>'.&mt('Output Format: [_1]',$output_selector).'</label>'.('&nbsp;'x3));
1.59      matthew  1325:     }
1.159     www      1326:     $r->print('<label>'.&mt('Student Status: [_1]',$status_select)."</label>\n");
1.105     matthew  1327:     $r->print('<input type="submit" value="'.&mt('Update Display').'" />'.
                   1328:               "\n</p>\n");
1.103     matthew  1329:     #
                   1330:     # Print the classlist
                   1331:     $r->print('<h2>'.&mt('Current Class List').'</h2>');
1.56      matthew  1332:     my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
1.164     albertel 1333: 
                   1334:     if (exists($permission->{'view_section'})) {
                   1335: 	my $sec = &Apache::loncoursedata::CL_SECTION();	
                   1336: 	foreach my $student (keys(%{$classlist})) {
                   1337: 	    if ($classlist->{$student}[$sec] ne $permission->{'view_section'}) {
                   1338: 		delete($classlist->{$student});
                   1339: 	    }
                   1340: 	}
                   1341:     }
                   1342: 
1.56      matthew  1343:     if (! defined($classlist)) {
1.94      sakharuk 1344:         $r->print(&mt('There are no students currently enrolled.')."\n");
1.40      matthew  1345:     } else {
                   1346:         # Print out the available choices
1.127     albertel 1347:         if ($env{'form.action'} eq 'modifystudent') {
1.110     matthew  1348:             &show_class_list($r,'view','modify',
1.127     albertel 1349:                              $env{'form.Status'},$classlist,$keylist);
1.110     matthew  1350:         } else {
1.127     albertel 1351:             &show_class_list($r,$env{'form.output'},'aboutme',
                   1352:                              $env{'form.Status'},$classlist,$keylist);
1.50      matthew  1353:         }
1.41      matthew  1354:     }
                   1355: }
                   1356: 
1.40      matthew  1357: # =================================================== Show student list to drop
                   1358: sub show_class_list {
1.110     matthew  1359:     my ($r,$mode,$linkto,$statusmode,$classlist,$keylist)=@_;
1.127     albertel 1360:     my $cid=$env{'request.course.id'};
1.142     raeburn  1361:     my $cdom = $env{'course.'.$cid.'.domain'};
                   1362:     my $cnum = $env{'course.'.$cid.'.num'};
                   1363:     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
                   1364:                                               $classlist,$keylist,$cdom,$cnum);
1.60      matthew  1365:     #
                   1366:     # Variables for excel output
1.104     matthew  1367:     my ($excel_workbook, $excel_sheet, $excel_filename,$row,$format);
1.60      matthew  1368:     #
1.103     matthew  1369:     # Variables for csv output
                   1370:     my ($CSVfile,$CSVfilename);
                   1371:     #
1.127     albertel 1372:     my $sortby = $env{'form.sortby'};
1.142     raeburn  1373:     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end|type)$/) {
1.53      matthew  1374:         $sortby = 'username';
                   1375:     }
1.134     raeburn  1376:     if (! exists($env{'form.displayphotos'})) {
                   1377:         $env{'form.displayphotos'} = 'off';
                   1378:     }
                   1379:     my $displayphotos = $env{'form.displayphotos'};
                   1380: 
1.170     www      1381:     if (! exists($env{'form.displayclickers'})) {
                   1382:         $env{'form.displayclickers'} = 'off';
                   1383:     }
                   1384:     my $displayclickers = $env{'form.displayclickers'};
                   1385: 
1.42      matthew  1386:     # Print out header 
1.114     raeburn  1387:     unless ($mode eq 'autoenroll') {
                   1388:         $r->print(<<END);
1.127     albertel 1389: <input type="hidden" name="state" value="$env{'form.state'}" />
1.114     raeburn  1390: END
                   1391:     }
1.103     matthew  1392:     $r->print(<<END);
                   1393: <input type="hidden" name="sortby" value="$sortby" />
1.134     raeburn  1394: <input type="hidden" name="displayphotos" value="$displayphotos" />
1.170     www      1395: <input type="hidden" name="displayclickers" value="$displayclickers" />
1.103     matthew  1396: END
1.114     raeburn  1397:     if ($mode eq 'html' || $mode eq 'view' || $mode eq 'autoenroll') {
1.50      matthew  1398:         if ($linkto eq 'aboutme') {
1.142     raeburn  1399:             $r->print(&mt("Select a user name to view the user's personal page."));
1.50      matthew  1400:         } elsif ($linkto eq 'modify') {
1.142     raeburn  1401:             $r->print(&mt("Select a user name to modify the student's information"));
1.50      matthew  1402:         }
1.94      sakharuk 1403: 	my %lt=&Apache::lonlocal::texthash(
1.110     matthew  1404:                                            'usrn'   => "username",
                   1405:                                            'dom'    => "domain",
                   1406:                                            'sn'     => "student name",
                   1407:                                            'sec'    => "section",
1.142     raeburn  1408:                                            'grp'    => "active groups",
1.110     matthew  1409:                                            'start'  => "start date",
                   1410:                                            'end'    => "end date",
1.134     raeburn  1411:                                            'type'   => "enroll type/action",
1.163     albertel 1412: 					   'email'  => "email address",
1.170     www      1413:                                            'clicker'=> "clicker id",
1.134     raeburn  1414:                                            'photo'  => "photo",
1.94      sakharuk 1415: 					   );
1.114     raeburn  1416:         unless ($mode eq 'autoenroll') {
                   1417:             $r->print(<<END);
1.59      matthew  1418: <input type="hidden" name="sname"  value="" />
                   1419: <input type="hidden" name="sdom"   value="" />
1.114     raeburn  1420: END
                   1421:         }
1.136     raeburn  1422:         if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
1.134     raeburn  1423:             $r->print('
                   1424: <script type="text/javascript">
                   1425: function photowindow(photolink) {
                   1426:     var title = "Photo_Viewer";
                   1427:     var options = "scrollbars=1,resizable=1,menubar=0";
                   1428:     options += ",width=240,height=240";
                   1429:     stdeditbrowser = open(photolink,title,options,"1");
                   1430:     stdeditbrowser.focus();
                   1431: }
                   1432: </script>
                   1433:            ');
                   1434:         }
1.115     raeburn  1435:         $r->print("
1.40      matthew  1436: <p>
1.139     albertel 1437: ".&Apache::loncommon::start_data_table()."
1.115     raeburn  1438: <tr>
                   1439:         ");
                   1440:         if ($mode eq 'autoenroll') {
                   1441:             $r->print("
                   1442:  <th><a href=\"javascript:document.studentform.sortby.value='type';document.studentform.submit();\">$lt{'type'}</a></th>
                   1443:             ");
                   1444:         } else {
                   1445:             $r->print("
                   1446: <th>Count</th>
                   1447:             ");
                   1448:         }
                   1449:         $r->print(<<END);
                   1450:     <th>
1.94      sakharuk 1451:        <a href="javascript:document.studentform.sortby.value='username';document.studentform.submit();">$lt{'usrn'}</a>
1.53      matthew  1452:     </th><th>
1.94      sakharuk 1453:        <a href="javascript:document.studentform.sortby.value='domain';document.studentform.submit();">$lt{'dom'}</a>
1.53      matthew  1454:     </th><th>
1.57      matthew  1455:        <a href="javascript:document.studentform.sortby.value='id';document.studentform.submit();">ID</a>
1.53      matthew  1456:     </th><th>
1.94      sakharuk 1457:        <a href="javascript:document.studentform.sortby.value='fullname';document.studentform.submit();">$lt{'sn'}</a>
1.53      matthew  1458:     </th><th>
1.94      sakharuk 1459:        <a href="javascript:document.studentform.sortby.value='section';document.studentform.submit();">$lt{'sec'}</a>
1.110     matthew  1460:     </th><th>
                   1461:        <a href="javascript:document.studentform.sortby.value='start';document.studentform.submit();">$lt{'start'}</a>
                   1462:     </th><th>
                   1463:        <a href="javascript:document.studentform.sortby.value='end';document.studentform.submit();">$lt{'end'}</a>
1.142     raeburn  1464:     </th><th>
                   1465:        <a href="javascript:document.studentform.sortby.value='groups';document.studentform.submit();">$lt{'grp'}</a>
1.163     albertel 1466:     </th><th>
                   1467:        <a href="javascript:document.studentform.sortby.value='email';document.studentform.submit();">$lt{'email'}</a>
1.53      matthew  1468:     </th>
1.40      matthew  1469: END
1.170     www      1470: 
                   1471: # Clicker display on or off?
                   1472: 
                   1473:         my %clicker_options = &Apache::lonlocal::texthash(
                   1474:                                                           'on' => 'Show',
                   1475:                                                           'off' => 'Hide',
                   1476:                                                          );
                   1477:         my $clickerchg = 'on';
                   1478:         if ($displayclickers eq 'on') {
                   1479:             $clickerchg = 'off';
                   1480:         }
                   1481:         $r->print('    <th>'."\n".'     '.
                   1482:             '<a href="javascript:document.studentform.displayclickers.value='.
                   1483:                       "'".$clickerchg."'".';document.studentform.submit();">'.
                   1484:                       $clicker_options{$clickerchg}.'</a>&nbsp;'.$lt{'clicker'}."\n".
                   1485:                       '    </th>'."\n");
                   1486: 
                   1487: # Photo display on or off?
1.136     raeburn  1488:         if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) {
1.135     albertel 1489:             my %photo_options = &Apache::lonlocal::texthash(
1.134     raeburn  1490:                                                             'on' => 'Show',
                   1491:                                                             'off' => 'Hide',
                   1492:                                                             );
                   1493:             my $photochg = 'on';
                   1494:             if ($displayphotos eq 'on') {
                   1495:                 $photochg = 'off';
                   1496:             }
                   1497:             $r->print('    <th>'."\n".'     '. 
                   1498:             '<a href="javascript:document.studentform.displayphotos.value='.
                   1499:                       "'".$photochg."'".';document.studentform.submit();">'.
                   1500:                       $photo_options{$photochg}.'</a>&nbsp;'.$lt{'photo'}."\n".
                   1501:                       '    </th>'."\n");
                   1502:         }
                   1503:         $r->print("  </tr>\n");
1.170     www      1504: 
                   1505: # Done with the HTML header line
                   1506: 
1.41      matthew  1507:     } elsif ($mode eq 'csv') {
1.103     matthew  1508: 	#
                   1509: 	# Open a file
                   1510: 	$CSVfilename = '/prtspool/'.
1.127     albertel 1511: 	    $env{'user.name'}.'_'.$env{'user.domain'}.'_'.
1.103     matthew  1512:             time.'_'.rand(1000000000).'.csv';
                   1513: 	unless ($CSVfile = Apache::File->new('>/home/httpd'.$CSVfilename)) {
                   1514: 	    $r->log_error("Couldn't open $CSVfilename for output $!");
                   1515: 	    $r->print("Problems occured in writing the csv file.  ".
                   1516: 		      "This error has been logged.  ".
                   1517: 		      "Please alert your LON-CAPA administrator.");
                   1518: 	    $CSVfile = undef;
                   1519: 	}
                   1520: 	#
                   1521: 	# Write headers and data to file
1.58      matthew  1522:         if($statusmode eq 'Expired') {
1.103     matthew  1523:             print $CSVfile '"'.&mt('Students with expired roles').'"'."\n";
1.58      matthew  1524:         }
1.147     albertel 1525:         if($statusmode eq 'Future') {
                   1526:             print $CSVfile '"'.&mt('Students with future roles').'"'."\n";
                   1527:         }
1.58      matthew  1528:         if ($statusmode eq 'Any') {
1.103     matthew  1529:             print $CSVfile '"'.join('","',map {
                   1530: 		&Apache::loncommon::csv_translate(&mt($_))
                   1531:                 } ("username","domain","ID","student name",
1.163     albertel 1532:                    "section","start date","end date","status",
                   1533: 		   "active groups","email address"))
1.142     raeburn  1534:                   .'"'."\n";
1.58      matthew  1535:         } else {
1.103     matthew  1536:             print $CSVfile '"'.join('","',map {
                   1537: 		&Apache::loncommon::csv_translate(&mt($_))
                   1538:                 } ("username","domain","ID","student name",
1.163     albertel 1539:                    "section","start date","end date",
                   1540: 		   "active groups","email address")).'"'."\n";
1.58      matthew  1541:         }
1.60      matthew  1542:     } elsif ($mode eq 'excel') {
                   1543:         # Create the excel spreadsheet
1.126     matthew  1544:         ($excel_workbook,$excel_filename,$format) = 
                   1545:             &Apache::loncommon::create_workbook($r);
                   1546:         return if (! defined($excel_workbook));
1.60      matthew  1547:         $excel_sheet = $excel_workbook->addworksheet('classlist');
                   1548:         #
1.76      albertel 1549:         my $description = 'Class List for '.
1.127     albertel 1550:             $env{'course.'.$env{'request.course.id'}.'.description'};
1.104     matthew  1551:         $excel_sheet->write($row++,0,$description,$format->{'h1'});
1.60      matthew  1552:         #
                   1553:         $excel_sheet->write($row++,0,["username","domain","ID",
1.110     matthew  1554:                                       "student name","section",
1.142     raeburn  1555:                                       "start date","end date","status",
1.163     albertel 1556:                                       "active groups","email address"],
1.110     matthew  1557:                             $format->{'bold'});
1.41      matthew  1558:     }
1.170     www      1559: 
                   1560: # Done with header lines in all formats
                   1561: 
1.56      matthew  1562:     #
                   1563:     # Sort the students
                   1564:     my %index;
                   1565:     my $i;
                   1566:     foreach (@$keylist) {
                   1567:         $index{$_} = $i++;
                   1568:     }
1.142     raeburn  1569:     $index{'groups'} = scalar(@{$keylist});
1.56      matthew  1570:     my $index  = $index{$sortby};
                   1571:     my $second = $index{'username'};
                   1572:     my $third  = $index{'domain'};
1.53      matthew  1573:     my @Sorted_Students = sort {
1.56      matthew  1574:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   1575:             ||
                   1576:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   1577:             ||
                   1578:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   1579:         } (keys(%$classlist));
1.108     matthew  1580:     my $studentcount = 0;
1.115     raeburn  1581:     my $autocount = 0;
                   1582:     my $manualcount = 0;
                   1583:     my $unlockcount = 0;
                   1584:     my $lockcount = 0;
1.53      matthew  1585:     foreach my $student (@Sorted_Students) {
1.110     matthew  1586:         my $sdata = $classlist->{$student};
1.142     raeburn  1587:         my $groups = $classgroups->{$student};
1.110     matthew  1588:         my $username = $sdata->[$index{'username'}];
                   1589:         my $domain   = $sdata->[$index{'domain'}];
                   1590:         my $section  = $sdata->[$index{'section'}];
1.142     raeburn  1591:         my $active_groups;
                   1592:         if (ref($groups->{active}) eq 'HASH') {
                   1593:             $active_groups = join(', ',keys(%{$groups->{'active'}}));
                   1594:         }
1.110     matthew  1595:         my $name     = $sdata->[$index{'fullname'}];
                   1596:         my $id       = $sdata->[$index{'id'}];
                   1597:         my $status   = $sdata->[$index{'status'}];
1.163     albertel 1598:         next if (($statusmode ne 'Any') && ($status ne $statusmode));
1.110     matthew  1599:         my $start    = $sdata->[$index{'start'}];
                   1600:         my $end      = $sdata->[$index{'end'}];
1.115     raeburn  1601:         my $type     = $sdata->[$index{'type'}];
1.163     albertel 1602: 
                   1603: 	my %emails   = &Apache::loncommon::getemails($username,$domain);
                   1604: 	my $email;
1.168     raeburn  1605: 	if ($emails{'permanentemail'} =~ /\S/) {
                   1606: 	    $email = $emails{'permanentemail'};
1.163     albertel 1607: 	}
                   1608: 
1.114     raeburn  1609:         if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
                   1610:             if (! defined($start) || $start == 0) {
                   1611:                 $start = &mt('none');
                   1612:             } else {
                   1613:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1614:             }
                   1615:             if (! defined($end) || $end == 0) {
                   1616:                 $end = &mt('none');
                   1617:             } else {
                   1618:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1619:             }
1.139     albertel 1620: 	    $r->print(&Apache::loncommon::start_data_table_row());
1.115     raeburn  1621:             if ($mode eq 'autoenroll') {
                   1622:                 my $lockedtype = $sdata->[$index{'lockedtype'}];
                   1623:                 $studentcount++;
                   1624:                 my $cellentry;
                   1625:                 if ($type eq 'auto') {
1.131     albertel 1626:                     $cellentry = '<b>'.&mt('auto').'</b>&nbsp;<label><input type="checkbox" name="chgauto" value="'.$username.':'.$domain.'" />&nbsp;Change</label>';
1.115     raeburn  1627:                     $autocount ++;
                   1628:                 } else {
1.131     albertel 1629:                     $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  1630:                     $manualcount ++;
                   1631:                     if ($lockedtype) {
1.131     albertel 1632:                         $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Unlock').'</label>';
1.115     raeburn  1633:                         $unlockcount ++;
                   1634:                     } else {
1.131     albertel 1635:                         $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Lock').'</label>';
1.115     raeburn  1636:                         $lockcount ++;
                   1637:                     }
1.118     raeburn  1638:                     $cellentry .= '</nobr></td></tr></table>';
1.115     raeburn  1639:                 }
                   1640:                 $r->print("<td>$cellentry<td>\n    ");
                   1641:             } else {
                   1642:                 $r->print("<td>".(++$studentcount)."</td><td>\n    ");
                   1643:             }
1.51      matthew  1644:             if ($linkto eq 'nothing') {
                   1645:                 $r->print($username);
                   1646:             } elsif ($linkto eq 'aboutme') {
                   1647:                 $r->print(&Apache::loncommon::aboutmewrapper($username,
                   1648:                                                              $username,
                   1649:                                                              $domain));
                   1650:             } elsif ($linkto eq 'modify') {
1.59      matthew  1651:                 $r->print('<a href="'.
                   1652:                           "javascript:document.studentform.sname.value='".
                   1653:                           $username.
                   1654:                           "';document.studentform.sdom.value='".$domain.
                   1655:                           "';document.studentform.state.value='selected".
                   1656:                           "';document.studentform.submit();".'">'.
1.53      matthew  1657:                           $username."</a>\n");
1.50      matthew  1658:             }
1.51      matthew  1659:             $r->print(<<"END");
1.50      matthew  1660:     </td>
1.51      matthew  1661:     <td>$domain</td>
                   1662:     <td>$id</td>
                   1663:     <td>$name</td>
                   1664:     <td>$section</td>
1.110     matthew  1665:     <td>$start</td>
                   1666:     <td>$end</td>
1.142     raeburn  1667:     <td>$active_groups</td>
1.163     albertel 1668:     <td>$email</td>
1.114     raeburn  1669: END
1.170     www      1670: 
                   1671: # Clickers
                   1672:             if ($displayclickers eq 'on') {
                   1673:                my $clickers =
                   1674:                (&Apache::lonnet::userenvironment($domain,$username,'clickers'))[1];
                   1675:                if ($clickers!~/\w/) { $clickers='-'; }
                   1676:                $r->print('<td>'.$clickers.'</td>');
                   1677:             } else {
                   1678:                 $r->print('    <td>&nbsp;</td>  ');
                   1679:             }
                   1680: 
                   1681: # Photos
                   1682: 
1.134     raeburn  1683:             if ($env{'course.'.$env{'request.course.id'}.
1.136     raeburn  1684: 			 '.internal.showphoto'}) {
1.134     raeburn  1685:                 if ($displayphotos eq 'on') {
1.135     albertel 1686:                     my $imgurl = 
                   1687: 			&Apache::lonnet::retrievestudentphoto($domain,
                   1688: 							      $username,'gif',
                   1689: 							      'thumbnail');
1.134     raeburn  1690:                 
                   1691:                     $r->print('    <td align="right"><a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($domain,$username,'jpg')."'".')"><img src="'.$imgurl.'" border="1"></a></td>');
                   1692:                 } else {
                   1693:                     $r->print('    <td>&nbsp;</td>  ');
                   1694:                 }
                   1695:             }
1.139     albertel 1696: 	    $r->print(&Apache::loncommon::end_data_table_row());
1.51      matthew  1697:         } elsif ($mode eq 'csv') {
1.103     matthew  1698:             next if (! defined($CSVfile));
1.51      matthew  1699:             # no need to bother with $linkto
1.114     raeburn  1700:             if (! defined($start) || $start == 0) {
                   1701:                 $start = &mt('none');
                   1702:             } else {
                   1703:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1704:             }
                   1705:             if (! defined($end) || $end == 0) {
                   1706:                 $end = &mt('none');
                   1707:             } else {
                   1708:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1709:             }
1.51      matthew  1710:             my @line = ();
1.110     matthew  1711:             foreach ($username,$domain,$id,$name,$section,$start,$end) {
1.51      matthew  1712:                 push @line,&Apache::loncommon::csv_translate($_);
1.58      matthew  1713:             }
                   1714:             if ($statusmode eq 'Any') {
                   1715:                 push @line,&Apache::loncommon::csv_translate($status);
1.41      matthew  1716:             }
1.142     raeburn  1717:             push @line,&Apache::loncommon::csv_translate($active_groups);
1.163     albertel 1718:             push @line,&Apache::loncommon::csv_translate($email);
1.103     matthew  1719:             print $CSVfile '"'.join('","',@line).'"'."\n";
1.60      matthew  1720:         } elsif ($mode eq 'excel') {
1.110     matthew  1721:             $excel_sheet->write($row,0,[$username,$domain,$id,
                   1722:                                           $name,$section]);
                   1723:             my $col = 5;
                   1724:             foreach my $time ($start,$end) {
1.129     matthew  1725:                 if (defined($time) && $time != 0) {
                   1726:                     $excel_sheet->write($row,$col++,
1.110     matthew  1727:                                    &Apache::lonstathelpers::calc_serial($time),
                   1728:                                     $format->{'date'});
1.129     matthew  1729:                 } else {
                   1730:                     $excel_sheet->write($row,$col++,'none');
                   1731:                 }                    
1.110     matthew  1732:             }
                   1733:             $excel_sheet->write($row,$col++,$status);
1.142     raeburn  1734:             $excel_sheet->write($row,$col++,$active_groups);
1.163     albertel 1735:             $excel_sheet->write($row,$col++,$email);
1.110     matthew  1736:             $row++;
1.40      matthew  1737:         }
                   1738:     }
1.114     raeburn  1739:     if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
1.139     albertel 1740: 	$r->print(&Apache::loncommon::end_data_table().'<br />');
1.60      matthew  1741:     } elsif ($mode eq 'excel') {
                   1742:         $excel_workbook->close();
                   1743:         $r->print('<p><a href="'.$excel_filename.'">'.
1.94      sakharuk 1744:                   &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
1.103     matthew  1745:     } elsif ($mode eq 'csv') {
                   1746:         close($CSVfile);
                   1747:         $r->print('<a href="'.$CSVfilename.'">'.
                   1748:                   &mt('Your CSV file').'</a> is ready for download.'.
                   1749:                   "\n");
                   1750:         $r->rflush();
1.60      matthew  1751:     }
1.114     raeburn  1752:     if ($mode eq 'autoenroll') {
1.115     raeburn  1753:         return ($studentcount,$autocount,$manualcount,$lockcount,$unlockcount);
1.114     raeburn  1754:     }
1.115     raeburn  1755:     return;
1.40      matthew  1756: }
                   1757: 
1.50      matthew  1758: 
                   1759: #
                   1760: # print out form for modification of a single students data
                   1761: #
                   1762: sub print_modify_student_form {
                   1763:     my $r = shift();
                   1764:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.59      matthew  1765:                                             ['sdom','sname']);    
1.127     albertel 1766:     my $sname  = $env{'form.sname'};
                   1767:     my $sdom   = $env{'form.sdom'};
                   1768:     my $sortby = $env{'form.sortby'};
1.50      matthew  1769:     # determine the students name information
                   1770:     my %info=&Apache::lonnet::get('environment',
                   1771:                                   ['firstname','middlename',
1.168     raeburn  1772:                                    'lastname','generation','id',
                   1773:                                    'permanentemail'], $sdom, $sname);
1.50      matthew  1774:     my ($tmp) = keys(%info);
                   1775:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1776:         $r->print('<font color="#ff0000" size="+2">'.&mt('Error').'</font>'.
1.50      matthew  1777:                   '<p>'.
1.94      sakharuk 1778:                   &mt('Unable to retrieve environment data for').' '.$sname.
                   1779:                   &mt('in domain').' '.$sdom.'</p><p>'.
1.138     albertel 1780:                   &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p>'.&Apache::loncommon::end_page());
1.50      matthew  1781:         return;
                   1782:     }
                   1783:     # determine the students starting and ending times and section
                   1784:     my ($starttime,$endtime,$section) = &get_enrollment_data($sname,$sdom);
1.87      matthew  1785:     if ($starttime =~ /^error/) {
1.94      sakharuk 1786:         $r->print('<h2>'&mt('Error').'</h2>');
1.87      matthew  1787:         $r->print('<p>'.$starttime.'</p>');
                   1788:         return;
                   1789:     }
1.101     matthew  1790:     #
1.50      matthew  1791:     # Deal with date forms
1.101     matthew  1792:     my $current_date_description = '';
                   1793:     my $textdate = '';
                   1794: 
                   1795:     if (! defined($starttime) || $starttime == 0) {
                   1796:         $current_date_description = &mt('Current Starting Date: not set').
                   1797:             '<br />';
                   1798:     } else {
                   1799:         $current_date_description = 
                   1800:             &mt('Current Starting Date: [_1]',
                   1801:                 &Apache::lonlocal::locallocaltime($starttime)).'<br />';
                   1802:     }
                   1803:     if (! defined($endtime) || $endtime == 0) {
                   1804:         $current_date_description.= &mt('Current Ending Date: not set').
                   1805:             '<br />';
                   1806:     } else {
                   1807:         $current_date_description.= 
                   1808:             &mt('Current Ending Date: [_1]',
                   1809:                 &Apache::lonlocal::locallocaltime($endtime)).'<br />';
                   1810: 
                   1811:     }
1.173   ! raeburn  1812:     my $date_table = 
        !          1813:         &Apache::lonuserutils::date_setting_table($starttime,$endtime);
1.59      matthew  1814:     #
1.127     albertel 1815:     if (! exists($env{'form.Status'}) || 
1.147     albertel 1816:         $env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.127     albertel 1817:         $env{'form.Status'} = 'crap';
1.59      matthew  1818:     }
1.94      sakharuk 1819:     # Make sure student is enrolled in course
                   1820:     my %lt=&Apache::lonlocal::texthash(
                   1821: 	           'mef'   => "Modify Enrollment for",
                   1822:                    'odcc'  => "Only domain coordinators can change a users password.",
                   1823:                    'sn'    => "Student Name",
                   1824:                    'fn'    => "First",
                   1825:                    'mn'    => "Middle",
                   1826:                    'ln'    => "Last",
                   1827:                    'gen'   => "Generation",
1.168     raeburn  1828:                    'email' => "E-mail address",
1.94      sakharuk 1829:                    'sid'   => "Student ID",
                   1830:                    'disn'  => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1831:                    'sec'   => "Section",
                   1832:                    'sm'    => "Submit Modifications",
                   1833: 				       );
1.142     raeburn  1834: # Check if section name is valid
1.173   ! raeburn  1835:     my $section_check = &Apache::lonuserutils::section_check_js();
1.142     raeburn  1836:     $r->print(<<"END");
                   1837: <script type="text/javascript">
                   1838: $section_check
                   1839: function secverify(formname,caller) {
                   1840:     if (validate(caller) == "error") {
                   1841:         return;
                   1842:     } else {
                   1843:         formname.submit();
                   1844:     }
                   1845: }
                   1846: </script>
1.52      matthew  1847: <p>
                   1848: <font size="+1">
1.94      sakharuk 1849: $lt{'odcc'}
1.52      matthew  1850: </font>
                   1851: </p>
1.50      matthew  1852: <input type="hidden" name="slogin"  value="$sname"  />
                   1853: <input type="hidden" name="sdomain" value="$sdom" />
                   1854: <input type="hidden" name="action"  value="modifystudent" />
1.53      matthew  1855: <input type="hidden" name="state"   value="done" />
                   1856: <input type="hidden" name="sortby"  value="$sortby" />
1.127     albertel 1857: <input type="hidden" name="Status"  value="$env{'form.Status'}" />
1.168     raeburn  1858: <h3>$lt{'mef'} $info{'firstname'} $info{'middlename'} 
                   1859: $info{'lastname'} $info{'generation'}, $sname:$sdom</h3>
1.50      matthew  1860: <p>
1.94      sakharuk 1861: <b>$lt{'sn'}</b>
1.50      matthew  1862: <table>
1.94      sakharuk 1863: <tr><th>$lt{'fn'}</th><th>$lt{'mn'}</th><th>$lt{'ln'}</th><th>$lt{'gen'}</th></tr>
1.50      matthew  1864: <tr><td>
                   1865: <input type="text" name="firstname"  value="$info{'firstname'}"  /></td><td>
                   1866: <input type="text" name="middlename" value="$info{'middlename'}" /></td><td>
                   1867: <input type="text" name="lastname"   value="$info{'lastname'}"   /></td><td>
                   1868: <input type="text" name="generation" value="$info{'generation'}" /></td></tr>
                   1869: </table>
                   1870: </p><p>
1.168     raeburn  1871: <b>$lt{'email'}</b>: <input type="text" name="permanentemail" value="$info{'permanentemail'}" size="30" />
                   1872: </p><p>
1.160     albertel 1873: <b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12" />
1.52      matthew  1874: </p><p>
1.131     albertel 1875: <label>
1.160     albertel 1876: <input type="checkbox" name="forceid" /> 
1.94      sakharuk 1877: $lt{'disn'}
1.131     albertel 1878: </label>
1.53      matthew  1879: </p><p>
1.160     albertel 1880: <b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="14" />
1.50      matthew  1881: </p>
1.101     matthew  1882: <p>$current_date_description</p>
1.68      matthew  1883: <p>$date_table</p>
1.142     raeburn  1884: <input type="button" value="$lt{'sm'}" onClick="secverify(this.form,this.form.section)" />
1.50      matthew  1885: END
1.138     albertel 1886:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  1887:     return;
                   1888: }
                   1889: 
                   1890: #
                   1891: # modify a single students section 
                   1892: #
                   1893: sub modify_single_student {
1.138     albertel 1894:     my ($r) = @_;
1.68      matthew  1895:     #
1.80      matthew  1896:     # Remove non alphanumeric values from the section
1.127     albertel 1897:     $env{'form.section'} =~ s/\W//g;
1.77      matthew  1898:     #
1.68      matthew  1899:     # Do the date defaults first
1.173   ! raeburn  1900:     my ($starttime,$endtime) = &Apache::lonuserutils::get_dates_from_form();
1.127     albertel 1901:     if ($env{'form.makedatesdefault'}) {
1.173   ! raeburn  1902:         $r->print(&Apache::lonuserutils::make_dates_default($starttime,
        !          1903:                                                             $endtime));
1.68      matthew  1904:     }
1.59      matthew  1905:     # Get the 'sortby' and 'Status' variables so the user goes back to their
                   1906:     # previous screen
1.127     albertel 1907:     my $sortby = $env{'form.sortby'};
                   1908:     my $status = $env{'form.Status'};
1.53      matthew  1909:     #
                   1910:     # We always need this information
1.127     albertel 1911:     my $slogin     = $env{'form.slogin'};
                   1912:     my $sdom       = $env{'form.sdomain'};
1.53      matthew  1913:     #
                   1914:     # Get the old data
                   1915:     my %old=&Apache::lonnet::get('environment',
                   1916:                                  ['firstname','middlename',
1.168     raeburn  1917:                                   'lastname','generation','id',
                   1918:                                   'permanentemail'],$sdom, $slogin);
1.59      matthew  1919:     $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin,
1.127     albertel 1920:                                                   $env{'request.course.id'});
1.53      matthew  1921:     my ($tmp) = keys(%old);
                   1922:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.162     albertel 1923:         $r->print(&mt('There was an error determining the environment values for')." $slogin : $sdom.");
1.53      matthew  1924:         return;
                   1925:     }
                   1926:     undef $tmp;
                   1927:     #
                   1928:     # Get the new data
1.127     albertel 1929:     my $firstname  = $env{'form.firstname'};
                   1930:     my $middlename = $env{'form.middlename'};
                   1931:     my $lastname   = $env{'form.lastname'};
                   1932:     my $generation = $env{'form.generation'};
1.168     raeburn  1933:     my $permanentemail = $env{'form.permanentemail'};
1.127     albertel 1934:     my $section    = $env{'form.section'};
                   1935:     my $courseid   = $env{'request.course.id'};
                   1936:     my $sid        = $env{'form.id'};
1.50      matthew  1937:     my $displayable_starttime = localtime($starttime);
                   1938:     my $displayable_endtime   = localtime($endtime);
1.53      matthew  1939:     # 
                   1940:     # check for forceid override
1.63      matthew  1941:     if ((defined($old{'id'})) && ($old{'id'} ne '') && 
1.127     albertel 1942:         ($sid ne $old{'id'}) && (! exists($env{'form.forceid'}))) {
1.94      sakharuk 1943:         $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  1944:         $sid = $old{'id'};
                   1945:     }
                   1946:     #
1.50      matthew  1947:     # talk to the user about what we are going to do
1.94      sakharuk 1948:     my %lt=&Apache::lonlocal::texthash(
                   1949: 	           'mdu'   => "Modifying data for user",
                   1950:                    'si'    => "Student Information",
                   1951:                    'fd'    => "Field",
                   1952:                    'ov'    => "Old Value",
                   1953:                    'nv'    => "New Value",
                   1954:                    'fn'    => "First name",
                   1955:                    'mn'    => "Middle name",
                   1956:                    'ln'    => "Last name",
                   1957:                    'gen'   => "Generation",
1.168     raeburn  1958:                    'em'    => "E-mail address",
1.94      sakharuk 1959:                    'sec'   => "Section",
                   1960:                    'ri'    => "Role Information",
                   1961:                    'st'    => "Start Time",
                   1962:                    'et'    => "End Time",
                   1963: 				       );
1.50      matthew  1964:     $r->print(<<END);
1.168     raeburn  1965:     <h3>$lt{'mdu'} $slogin:$sdom </h3>
                   1966: END
                   1967:     $r->print(<<END);
1.50      matthew  1968: <table>
1.168     raeburn  1969:  <tr>
                   1970:   <td>
                   1971:     <table class="LC_nested_outer">
                   1972:      <tr>
                   1973:       <th>$lt{si}</th>
                   1974:      </tr>
                   1975:      <tr>
                   1976:       <td>
                   1977:        <table class="LC_nested">
                   1978:         <tr class="LC_info_row">
                   1979:          <td class="LC_left_item"> $lt{'fd'} </td>
                   1980:          <td class="LC_left_item"> $lt{'ov'} </td>
                   1981:          <td class="LC_left_item"> $lt{'nv'} </td>
                   1982:         </tr>
                   1983:         <tr class="LC_odd_row">
                   1984:          <td class="LC_left_item"> <b>$lt{'fn'}</b> </td>
                   1985:          <td class="LC_left_item"> $old{'firstname'} </td>
                   1986:          <td class="LC_left_item"> $firstname </td>
                   1987:         </tr>
                   1988:         <tr>
                   1989:          <td class="LC_left_item"> <b>$lt{'mn'}</b> </td>
                   1990:          <td class="LC_left_item"> $old{'middlename'} </td>
                   1991:          <td class="LC_left_item"> $middlename </td>
                   1992:         </tr>
                   1993:         <tr class="LC_odd_row">
                   1994:          <td class="LC_left_item"> <b>$lt{'ln'}</b> </td>
                   1995:          <td class="LC_left_item"> $old{'lastname'} </td>
                   1996:          <td class="LC_left_item"> $lastname </td>
                   1997:         </tr>
                   1998:         <tr>
                   1999:          <td class="LC_left_item"> <b>$lt{'gen'}</b> </td>
                   2000:          <td class="LC_left_item"> $old{'generation'} </td>
                   2001:          <td class="LC_left_item"> $generation </td>
                   2002:         </tr>
                   2003:         <tr class="LC_odd_row">
                   2004:          <td class="LC_left_item"> <b>ID</b> </td>
                   2005:          <td class="LC_left_item"> $old{'id'} </td>
                   2006:          <td class="LC_left_item"> $sid </td>
                   2007:         </tr>
                   2008:         <tr>
                   2009:          <td class="LC_left_item"> <b>$lt{'em'}</b> </td>
                   2010:          <td class="LC_left_item"> $old{'permanentemail'} </td>
                   2011:          <td class="LC_left_item"> $permanentemail </td>
                   2012:         <tr class="LC_odd_row">
                   2013:          <td> <b>$lt{'sec'}</b> </td>
                   2014:          <td> $old{'section'} </td>
                   2015:          <td> $section</td>
                   2016:         </tr>
                   2017:        </table>
                   2018:       </td>
                   2019:      </tr>
                   2020:    </table>
                   2021:    <br />
                   2022:    <table class="LC_nested_outer">
                   2023:      <tr>
                   2024:       <th>$lt{'ri'}</th>
                   2025:      </tr>
                   2026:      <tr>
                   2027:       <td>
                   2028:        <table class="LC_nested">
                   2029:         <tr class="LC_odd_row">
                   2030:          <td class="LC_left_item"><b>$lt{'st'}:</b></td>
                   2031:          <td class="LC_right_item"> $displayable_starttime </td>
                   2032:         </tr>
                   2033:         <tr>
                   2034:          <td class="LC_left_item"><b>$lt{'et'}:</b></td>
                   2035:          <td class="LC_right_item"> $displayable_endtime   </td>
                   2036:         </tr>
                   2037:        </table>
                   2038:       </td>
                   2039:      </tr>
                   2040:     </table>
                   2041:   </td>
                   2042:  </tr>
1.50      matthew  2043: </table>
1.52      matthew  2044: <p>
1.50      matthew  2045: END
1.53      matthew  2046:     #
1.63      matthew  2047:     # Send request(s) to modify data (final undef is for 'desiredhost',
                   2048:     # which is a moot point because the student already has an account.
1.173   ! raeburn  2049:     my $modify_section_results = 
        !          2050:         &Apache::lonuserutils::modifystudent($sdom,$slogin,
        !          2051:                                              $env{'request.course.id'},
        !          2052:                                              $section,undef);
1.63      matthew  2053:     if ($modify_section_results !~ /^ok/) {
1.94      sakharuk 2054:         $r->print(&mt('An error occured during the attempt to change the section for this student.')."<br />");
1.63      matthew  2055:     }
1.52      matthew  2056:     my $roleresults = &Apache::lonnet::modifystudent
1.53      matthew  2057:         ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname,
1.168     raeburn  2058:          $generation,$section,$endtime,$starttime,$env{'form.forceid'},
                   2059:          undef,$permanentemail);
                   2060:     if ($old{'permanentemail'} ne $permanentemail) {
                   2061:         &Apache::loncommon::flush_email_cache($slogin,$sdom);
                   2062:     }
1.53      matthew  2063:     if ($roleresults eq 'refused' ) {
1.94      sakharuk 2064:         $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  2065:     } elsif ($roleresults !~ /ok/) {
1.94      sakharuk 2066:         $r->print(&mt('An error occurred during the attempt to change the role information for this student.')."  <br />".
                   2067:                   &mt('The error reported was')." ".
1.50      matthew  2068:                   $roleresults);
1.53      matthew  2069:         &Apache::lonnet::logthis("londropadd:failed attempt to modify student".
1.162     albertel 2070:                                  " data for ".$slogin." : ".$sdom." by ".
                   2071:                                  $env{'user.name'}." : ".$env{'user.domain'}.
1.53      matthew  2072:                                  ":".$roleresults);
1.50      matthew  2073:     } else { # everything is okay!
1.94      sakharuk 2074:         $r->print(&mt('Student information updated successfully.')." <br />".
                   2075:                   &mt('The student must log out and log in again to see these changes.'));
1.50      matthew  2076:     }
1.94      sakharuk 2077:     my $Masd=&mt('Modify another students data');
1.50      matthew  2078:     $r->print(<<END);
1.52      matthew  2079: </p><p>
1.59      matthew  2080: <input type="hidden" name="action" value="modifystudent" />
                   2081: <input type="hidden" name="sortby" value="$sortby" />
                   2082: <input type="hidden" name="Status" value="$status" />
1.94      sakharuk 2083: <a href="javascript:document.studentform.submit();">$Masd</a>
1.50      matthew  2084: END
1.138     albertel 2085:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  2086:     return;
                   2087: }
                   2088: 
                   2089: sub get_enrollment_data {
                   2090:     my ($sname,$sdomain) = @_;
1.127     albertel 2091:     my $courseid = $env{'request.course.id'};
1.151     albertel 2092:     my $cdom = $env{'course.'.$courseid.'.domain'};
                   2093:     my $cnum = $env{'course.'.$courseid.'.num'};
1.50      matthew  2094:     my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname);
                   2095:     my ($tmp) = keys(%roles);
                   2096:     # Bail out if we were unable to get the students roles
1.87      matthew  2097:     return ('error'.$tmp) if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.50      matthew  2098:     # Go through the roles looking for enrollment in this course
                   2099:     my ($end,$start) = (undef,undef);
                   2100:     my $section = '';
                   2101:     my $count = scalar(keys(%roles));
                   2102:     while (my ($course,$role) = each(%roles)) {
1.150     albertel 2103:         if ($course=~m{^/\Q$cdom\E/\Q$cnum\E/*\s*(\w+)*_st$} ) {
1.50      matthew  2104:             #
                   2105:             # Get active role
                   2106:             $section=$1;
                   2107:             (undef,$end,$start)=split(/\_/,$role);
                   2108:             my $now=time;
                   2109:             my $notactive=0;
                   2110:             if ($start) {
                   2111:                 if ($now<$start) { $notactive=1; }
                   2112:             }
                   2113:             if ($end) {
                   2114:                 if ($now>$end) { $notactive=1; }
                   2115:             } 
                   2116:             unless ($notactive) { return ($start,$end,$section); }
                   2117:         }
                   2118:     }
                   2119:     return ($start,$end,$section);
                   2120: }
                   2121: 
1.56      matthew  2122: #################################################
                   2123: #################################################
                   2124: 
                   2125: =pod
                   2126: 
                   2127: =item show_drop_list
                   2128: 
                   2129: Display a list of students to drop
                   2130: Inputs: 
                   2131: 
                   2132: =over 4
                   2133: 
                   2134: =item $r, Apache request
                   2135: 
                   2136: =item $classlist, hash pointer returned from loncoursedata::get_classlist();
                   2137: 
                   2138: =item $keylist, array pointer returned from loncoursedata::get_classlist() 
                   2139: which describes the order elements are stored in the %$classlist values.
                   2140: 
                   2141: =item $nosort, if true, sorting links are omitted.
                   2142: 
                   2143: =back
                   2144: 
                   2145: =cut
                   2146: 
                   2147: #################################################
                   2148: #################################################
1.11      www      2149: sub show_drop_list {
1.56      matthew  2150:     my ($r,$classlist,$keylist,$nosort)=@_;
1.127     albertel 2151:     my $cid=$env{'request.course.id'};
                   2152:     if (! exists($env{'form.sortby'})) {
1.59      matthew  2153:         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   2154:                                                 ['sortby']);
                   2155:     }
1.127     albertel 2156:     my $sortby = $env{'form.sortby'};
1.142     raeburn  2157:     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) {
1.54      matthew  2158:         $sortby = 'username';
                   2159:     }
1.142     raeburn  2160:     my $cdom = $env{'course.'.$cid.'.domain'};
                   2161:     my $cnum = $env{'course.'.$cid,'.num'};
                   2162:     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
1.143     raeburn  2163:                                               $classlist,$keylist,$cdom,$cnum);
1.56      matthew  2164:     #
1.54      matthew  2165:     my $action = "drop";
                   2166:     $r->print(<<END);
                   2167: <input type="hidden" name="sortby" value="$sortby" />
                   2168: <input type="hidden" name="action" value="$action" />
1.50      matthew  2169: <input type="hidden" name="state"  value="done" />
1.32      matthew  2170: <script>
1.51      matthew  2171: function checkAll(field) {
1.32      matthew  2172:     for (i = 0; i < field.length; i++)
                   2173:         field[i].checked = true ;
                   2174: }
                   2175: 
1.51      matthew  2176: function uncheckAll(field) {
1.32      matthew  2177:     for (i = 0; i < field.length; i++)
                   2178:         field[i].checked = false ;
                   2179: }
                   2180: </script>
                   2181: <p>
1.26      matthew  2182: <input type="hidden" name="phase" value="four">
1.56      matthew  2183: END
                   2184: 
1.110     matthew  2185: my %lt=&Apache::lonlocal::texthash('usrn'   => "username",
                   2186:                                    'dom'    => "domain",
                   2187:                                    'sn'     => "student name",
                   2188:                                    'sec'    => "section",
                   2189:                                    'start'  => "start date",
                   2190:                                    'end'    => "end date",
1.142     raeburn  2191:                                    'groups' => "active groups",
1.110     matthew  2192:                                    );
1.56      matthew  2193:     if ($nosort) {
1.139     albertel 2194: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  2195:         $r->print(<<END);
                   2196: <tr>
                   2197:     <th>&nbsp;</th>
1.94      sakharuk 2198:     <th>$lt{'usrn'}</th>
                   2199:     <th>$lt{'dom'}</th>
1.56      matthew  2200:     <th>ID</th>
1.94      sakharuk 2201:     <th>$lt{'sn'}</th>
                   2202:     <th>$lt{'sec'}</th>
1.110     matthew  2203:     <th>$lt{'start'}</th>
                   2204:     <th>$lt{'end'}</th>
1.142     raeburn  2205:     <th>$lt{'groups'}</th>
1.56      matthew  2206: </tr>
                   2207: END
                   2208: 
                   2209:     } else  {
1.139     albertel 2210: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  2211:         $r->print(<<END);
1.54      matthew  2212: <tr><th>&nbsp;</th>
                   2213:     <th>
1.94      sakharuk 2214:        <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a>
1.54      matthew  2215:     </th><th>
1.94      sakharuk 2216:        <a href="/adm/dropadd?action=$action&sortby=domain">$lt{'dom'}</a>
1.54      matthew  2217:     </th><th>
                   2218:        <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
                   2219:     </th><th>
1.94      sakharuk 2220:        <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a>
1.54      matthew  2221:     </th><th>
1.94      sakharuk 2222:        <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a>
1.110     matthew  2223:     </th><th>
                   2224:        <a href="/adm/dropadd?action=$action&sortby=start">$lt{'start'}</a>
                   2225:     </th><th>
                   2226:        <a href="/adm/dropadd?action=$action&sortby=end">$lt{'end'}</a>
1.142     raeburn  2227:     </th><th>
                   2228:        <a href="/adm/dropadd?action=$action&sortby=groups">$lt{'groups'}</a>
1.54      matthew  2229:     </th>
                   2230: </tr>
1.26      matthew  2231: END
1.56      matthew  2232:     }
                   2233:     #
                   2234:     # Sort the students
                   2235:     my %index;
                   2236:     my $i;
                   2237:     foreach (@$keylist) {
                   2238:         $index{$_} = $i++;
                   2239:     }
1.142     raeburn  2240:     $index{'groups'} = scalar(@$keylist);
1.56      matthew  2241:     my $index  = $index{$sortby};
                   2242:     my $second = $index{'username'};
                   2243:     my $third  = $index{'domain'};
1.54      matthew  2244:     my @Sorted_Students = sort {
1.56      matthew  2245:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   2246:             ||
                   2247:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   2248:             ||
                   2249:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   2250:         } (keys(%$classlist));
1.54      matthew  2251:     foreach my $student (@Sorted_Students) {
1.52      matthew  2252:         my $error;
1.110     matthew  2253:         my $sdata = $classlist->{$student};
                   2254:         my $username = $sdata->[$index{'username'}];
                   2255:         my $domain   = $sdata->[$index{'domain'}];
                   2256:         my $section  = $sdata->[$index{'section'}];
                   2257:         my $name     = $sdata->[$index{'fullname'}];
                   2258:         my $id       = $sdata->[$index{'id'}];
                   2259:         my $start    = $sdata->[$index{'start'}];
                   2260:         my $end      = $sdata->[$index{'end'}];
1.142     raeburn  2261:         my $groups = $classgroups->{$student};
                   2262:         my $active_groups;
                   2263:         if (ref($groups->{active}) eq 'HASH') {
                   2264:             $active_groups = join(', ',keys(%{$groups->{'active'}}));
                   2265:         }
1.110     matthew  2266:         if (! defined($start) || $start == 0) {
                   2267:             $start = &mt('none');
                   2268:         } else {
                   2269:             $start = &Apache::lonlocal::locallocaltime($start);
                   2270:         }
                   2271:         if (! defined($end) || $end == 0) {
                   2272:             $end = &mt('none');
                   2273:         } else {
                   2274:             $end = &Apache::lonlocal::locallocaltime($end);
                   2275:         }
                   2276:         my $status   = $sdata->[$index{'status'}];
1.51      matthew  2277:         next if ($status ne 'Active');
                   2278:         #
1.139     albertel 2279:         $r->print(&Apache::loncommon::start_data_table_row());
1.51      matthew  2280:         $r->print(<<"END");
                   2281:     <td><input type="checkbox" name="droplist" value="$student"></td>
                   2282:     <td>$username</td>
                   2283:     <td>$domain</td>
                   2284:     <td>$id</td>
                   2285:     <td>$name</td>
                   2286:     <td>$section</td>
1.110     matthew  2287:     <td>$start</td>
                   2288:     <td>$end</td>
1.142     raeburn  2289:     <td>$active_groups</td>
1.26      matthew  2290: END
1.139     albertel 2291:         $r->print(&Apache::loncommon::end_data_table_row());
1.25      matthew  2292:     }
1.139     albertel 2293:     $r->print(&Apache::loncommon::end_data_table().'<br />');
1.111     matthew  2294:     %lt=&Apache::lonlocal::texthash(
1.94      sakharuk 2295: 	               'dp'   => "Drop Students",
                   2296:                        'ca'   => "check all",
                   2297:                        'ua'   => "uncheck all",
                   2298: 				       );
1.32      matthew  2299:     $r->print(<<"END");
                   2300: </p><p>
1.94      sakharuk 2301: <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)"> &nbsp;
                   2302: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)"> 
                   2303: <p><input type=submit value="$lt{'dp'}"></p>
1.32      matthew  2304: END
1.51      matthew  2305:     return;
1.10      www      2306: }
                   2307: 
1.48      matthew  2308: #
                   2309: # Print out the initial form to get the courselist file
                   2310: #
                   2311: sub print_first_courselist_upload_form {
                   2312:     my $r=shift;
1.88      matthew  2313:     my $str;
                   2314:     $str  = '<input type="hidden" name="phase" value="two">';
                   2315:     $str .= '<input type="hidden" name="action" value="upload" />';
                   2316:     $str .= '<input type="hidden"   name="state"  value="got_file" />';
                   2317:     $str .= "<h3>".&mt('Upload a class list')."</h3>\n";
                   2318:     $str .= &Apache::loncommon::upfile_select_html();
                   2319:     $str .= "<p>\n";
                   2320:     $str .= '<input type="submit" name="fileupload" value="'.
                   2321:         &mt('Upload class list').'">'."\n";
1.131     albertel 2322:     $str .= '<label><input type="checkbox" name="noFirstLine" /> '.
                   2323:         &mt('Ignore First Line')."</label></p>\n";
1.88      matthew  2324:     $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
1.92      sakharuk 2325:                          &mt("How do I create a class list from a spreadsheet")).
1.88      matthew  2326:                              "<br />\n";
                   2327:     $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
1.92      sakharuk 2328:                            &mt("How do I create a CSV file from a spreadsheet")).
1.88      matthew  2329:                                "<br />\n";
1.138     albertel 2330:     $str .= &Apache::loncommon::end_page();
1.88      matthew  2331:     $r->print($str);
1.48      matthew  2332:     return;
                   2333: }
                   2334: 
1.10      www      2335: # ================================================= Drop/Add from uploaded file
                   2336: sub upfile_drop_add {
                   2337:     my $r=shift;
1.24      albertel 2338:     &Apache::loncommon::load_tmp_file($r);
                   2339:     my @studentdata=&Apache::loncommon::upfile_record_sep();
1.127     albertel 2340:     if($env{'form.noFirstLine'}){shift(@studentdata);}
                   2341:     my @keyfields = split(/\,/,$env{'form.keyfields'});
                   2342:     my $cid = $env{'request.course.id'};
1.25      matthew  2343:     my %fields=();
1.127     albertel 2344:     for (my $i=0; $i<=$env{'form.nfields'}; $i++) {
                   2345:         if ($env{'form.upfile_associate'} eq 'reverse') {
                   2346:             if ($env{'form.f'.$i} ne 'none') {
                   2347:                 $fields{$keyfields[$i]}=$env{'form.f'.$i};
1.25      matthew  2348:             }
                   2349:         } else {
1.127     albertel 2350:             $fields{$env{'form.f'.$i}}=$keyfields[$i];
1.25      matthew  2351:         }
                   2352:     }
1.99      matthew  2353:     #
                   2354:     # Store the field choices away
                   2355:     foreach my $field (qw/username names 
                   2356:                        fname mname lname gen id sec ipwd email/) {
1.127     albertel 2357:         $env{'form.'.$field.'_choice'}=$fields{$field};
1.99      matthew  2358:     }
                   2359:     &Apache::loncommon::store_course_settings('enrollment_upload',
                   2360:                                               { 'username_choice' => 'scalar',
                   2361:                                                 'names_choice' => 'scalar',
                   2362:                                                 'fname_choice' => 'scalar',
                   2363:                                                 'mname_choice' => 'scalar',
                   2364:                                                 'lname_choice' => 'scalar',
                   2365:                                                 'gen_choice' => 'scalar',
                   2366:                                                 'id_choice' => 'scalar',
                   2367:                                                 'sec_choice' => 'scalar',
                   2368:                                                 'ipwd_choice' => 'scalar',
                   2369:                                                 'email_choice' => 'scalar' });
                   2370: 
1.26      matthew  2371:     #
1.68      matthew  2372:     my ($startdate,$enddate) = &get_dates_from_form();
1.127     albertel 2373:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  2374:         $r->print(&make_dates_default($startdate,$enddate));
                   2375:     }
1.31      matthew  2376:     # Determine domain and desired host (home server)
1.127     albertel 2377:     my $domain=$env{'form.lcdomain'};
                   2378:     my $desiredhost = $env{'form.lcserver'};
1.31      matthew  2379:     if (lc($desiredhost) eq 'default') {
                   2380:         $desiredhost = undef;
                   2381:     } else {
1.157     albertel 2382:         my %home_servers = &Apache::lonnet::get_servers($domain,'library');
1.31      matthew  2383:         if (! exists($home_servers{$desiredhost})) {
1.88      matthew  2384:             $r->print('<font color="#ff0000">'.&mt('Error').'</font>'.
                   2385:                       &mt('Invalid home server specified'));
1.138     albertel 2386:             $r->print(&Apache::loncommon::end_page());
1.31      matthew  2387:             return;
                   2388:         }
                   2389:     }
1.26      matthew  2390:     # Determine authentication mechanism
                   2391:     my $amode  = '';
                   2392:     my $genpwd = '';
1.127     albertel 2393:     if ($env{'form.login'} eq 'krb') {
1.47      albertel 2394:         $amode='krb';
1.127     albertel 2395: 	$amode.=$env{'form.krbver'};
                   2396:         $genpwd=$env{'form.krbarg'};
                   2397:     } elsif ($env{'form.login'} eq 'int') {
1.25      matthew  2398:         $amode='internal';
1.127     albertel 2399:         if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
                   2400:             $genpwd=$env{'form.intarg'};
1.25      matthew  2401:         }
1.127     albertel 2402:     } elsif ($env{'form.login'} eq 'loc') {
1.25      matthew  2403:         $amode='localauth';
1.127     albertel 2404:         if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {
                   2405:             $genpwd=$env{'form.locarg'};
1.79      matthew  2406:         }
                   2407:     }
                   2408:     if ($amode =~ /^krb/) {
                   2409:         if (! defined($genpwd) || $genpwd eq '') {
                   2410:             $r->print('<font color="red" size="+1">'.
1.88      matthew  2411:                       &mt('Unable to enroll students').'</font>  '.
                   2412:                       &mt('No Kerberos domain was specified.').'</p>');
1.79      matthew  2413:             $amode = ''; # This causes the loop below to be skipped
1.25      matthew  2414:         }
                   2415:     }
1.154     raeburn  2416:     if ( $domain eq &LONCAPA::clean_domain($domain)
1.150     albertel 2417: 	&& ($amode ne '')) {
1.26      matthew  2418:         #######################################
                   2419:         ##         Enroll Students           ##
                   2420:         #######################################
1.88      matthew  2421:         $r->print('<h3>'.&mt('Enrolling Students')."</h3>\n<p>\n");
1.25      matthew  2422:         my $count=0;
                   2423:         my $flushc=0;
                   2424:         my %student=();
1.142     raeburn  2425:         # Get information about course groups
1.143     raeburn  2426:         my %curr_groups = &Apache::longroup::coursegroups();
1.26      matthew  2427:         # Get new classlist
1.25      matthew  2428:         foreach (@studentdata) {
                   2429:             my %entries=&Apache::loncommon::record_sep($_);
1.26      matthew  2430:             # Determine student name
1.25      matthew  2431:             unless (($entries{$fields{'username'}} eq '') ||
                   2432:                     (!defined($entries{$fields{'username'}}))) {
1.26      matthew  2433:                 my ($fname, $mname, $lname,$gen) = ('','','','');
1.25      matthew  2434:                 if (defined($fields{'names'})) {
1.26      matthew  2435:                     ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
                   2436:                                             /([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.25      matthew  2437:                 } else {
                   2438:                     if (defined($fields{'fname'})) {
                   2439:                         $fname=$entries{$fields{'fname'}};
                   2440:                     }
                   2441:                     if (defined($fields{'mname'})) {
                   2442:                         $mname=$entries{$fields{'mname'}};
                   2443:                     }
                   2444:                     if (defined($fields{'lname'})) {
                   2445:                         $lname=$entries{$fields{'lname'}};
                   2446:                     }
                   2447:                     if (defined($fields{'gen'})) {
                   2448:                         $gen=$entries{$fields{'gen'}};
                   2449:                     }
                   2450:                 }
1.150     albertel 2451:                 if ($entries{$fields{'username'}}
                   2452: 		    ne &LONCAPA::clean_username($entries{$fields{'username'}})) {
1.88      matthew  2453:                     $r->print('<br />'.
                   2454:       &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
                   2455:           $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
                   2456:                               '</b>');
1.25      matthew  2457:                 } else {
1.26      matthew  2458:                     # determine section number
1.25      matthew  2459:                     my $sec='';
                   2460:                     my $username=$entries{$fields{'username'}};
                   2461:                     if (defined($fields{'sec'})) {
                   2462:                         if (defined($entries{$fields{'sec'}})) {
                   2463:                             $sec=$entries{$fields{'sec'}};
                   2464:                         }
                   2465:                     }
1.80      matthew  2466:                     # remove non alphanumeric values from section
                   2467:                     $sec =~ s/\W//g;
1.142     raeburn  2468:                     if ($sec eq "none" || $sec eq 'all') {
                   2469:                         $r->print('<br />'.
                   2470:       &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a reserved word.',
                   2471:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2472:                         next;
                   2473:                     } elsif (($sec ne '') && (exists($curr_groups{$sec}))) {
                   2474:                         $r->print('<br />'.
                   2475:       &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.',
                   2476:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2477:                         next;
                   2478:                     }
1.26      matthew  2479:                     # determine student id number
1.25      matthew  2480:                     my $id='';
                   2481:                     if (defined($fields{'id'})) {
                   2482:                         if (defined($entries{$fields{'id'}})) {
                   2483:                             $id=$entries{$fields{'id'}};
                   2484:                         }
                   2485:                         $id=~tr/A-Z/a-z/;
                   2486:                     }
1.73      www      2487:                     # determine email address
                   2488:                     my $email='';
                   2489:                     if (defined($fields{'email'})) {
                   2490:                         if (defined($entries{$fields{'email'}})) {
                   2491:                             $email=$entries{$fields{'email'}};
                   2492:                             unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
                   2493:                         }
                   2494:                     }
1.26      matthew  2495:                     # determine student password
1.25      matthew  2496:                     my $password='';
                   2497:                     if ($genpwd) { 
                   2498:                         $password=$genpwd; 
                   2499:                     } else {
                   2500:                         if (defined($fields{'ipwd'})) {
                   2501:                             if ($entries{$fields{'ipwd'}}) {
                   2502:                                 $password=$entries{$fields{'ipwd'}};
                   2503:                             }
                   2504:                         }
                   2505:                     }
1.56      matthew  2506:                     # Clean up whitespace
                   2507:                     foreach (\$domain,\$username,\$id,\$fname,\$mname,
                   2508:                              \$lname,\$gen,\$sec) {
                   2509:                         $$_ =~ s/(\s+$|^\s+)//g;
                   2510:                     }
1.127     albertel 2511:                     if ($password || $env{'form.login'} eq 'loc') {
1.173   ! raeburn  2512:                         &Apache::lonuserutils::modifystudent($domain,
        !          2513:                                                          $username,$cid,
        !          2514:                                                          $sec,$desiredhost);
1.25      matthew  2515:                         my $reply=&Apache::lonnet::modifystudent
                   2516:                             ($domain,$username,$id,$amode,$password,
                   2517:                              $fname,$mname,$lname,$gen,$sec,$enddate,
1.127     albertel 2518:                              $startdate,$env{'form.forceid'},$desiredhost,
1.73      www      2519:                              $email);
1.26      matthew  2520:                         if ($reply ne 'ok') {
1.72      matthew  2521:                             $reply =~ s/^error://;
1.88      matthew  2522:                             $r->print('<br />'.
                   2523:                 &mt('<b>[_1]</b>:  Unable to enroll: [_2]',$username,$reply));
1.10      www      2524:          		} else {
1.7       www      2525:                             $count++; $flushc++;
                   2526:                             $student{$username}=1;
1.6       www      2527:                             $r->print('. ');
1.7       www      2528:                             if ($flushc>15) {
                   2529: 				$r->rflush;
                   2530:                                 $flushc=0;
                   2531:                             }
1.6       www      2532:                         }
1.25      matthew  2533:                     } else {
1.88      matthew  2534:                         $r->print('<br />'.
                   2535:       &mt('<b>[_1]</b>: Unable to enroll.  No password specified.',$username)
                   2536:                                   );
1.25      matthew  2537:                     }
                   2538:                 }
1.26      matthew  2539:             }
                   2540:         } # end of foreach (@studentdata)
1.88      matthew  2541:         $r->print("</p>\n<p>\n".&mt('Processed [_1] student(s).',$count).
                   2542:                   "</p>\n");
                   2543:         $r->print("<p>\n".
                   2544:                   &mt('If active, the new role will be available when the '.
                   2545:                   'students next log in to LON-CAPA.')."</p>\n");
1.26      matthew  2546:         #####################################
                   2547:         #           Drop students           #
                   2548:         #####################################
1.127     albertel 2549:         if ($env{'form.fullup'} eq 'yes') {
1.88      matthew  2550:             $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");
1.26      matthew  2551:             #  Get current classlist
1.56      matthew  2552:             my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   2553:             if (! defined($classlist)) {
1.88      matthew  2554:                 $r->print(&mt('There are no students currently enrolled.').
                   2555:                           "\n");
1.56      matthew  2556:             } else {
                   2557:                 # Remove the students we just added from the list of students.
1.25      matthew  2558:                 foreach (@studentdata) {
                   2559:                     my %entries=&Apache::loncommon::record_sep($_);
                   2560:                     unless (($entries{$fields{'username'}} eq '') ||
                   2561:                             (!defined($entries{$fields{'username'}}))) {
1.56      matthew  2562:                         delete($classlist->{$entries{$fields{'username'}}.
1.26      matthew  2563:                                                 ':'.$domain});
1.25      matthew  2564:                     }
                   2565:                 }
1.56      matthew  2566:                 # Print out list of dropped students.
                   2567:                 &show_drop_list($r,$classlist,$keylist,'nosort');
1.25      matthew  2568:             }
                   2569:         }
1.26      matthew  2570:     } # end of unless
1.10      www      2571: }
                   2572: 
1.11      www      2573: # ================================================================== Phase four
                   2574: sub drop_student_list {
                   2575:     my $r=shift;
                   2576:     my $count=0;
1.128     albertel 2577:     my @droplist = &Apache::loncommon::get_env_multiple('form.droplist');
1.35      matthew  2578:     foreach (@droplist) {
1.26      matthew  2579:         my ($uname,$udom)=split(/\:/,$_);
1.56      matthew  2580:         # drop student
1.173   ! raeburn  2581:         my $result = &Apache::lonuserutils::modifystudent($udom,$uname,
        !          2582:                                                 $env{'request.course.id'});
1.37      matthew  2583:         if ($result eq 'ok' || $result eq 'ok:') {
1.88      matthew  2584:             $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>');
1.59      matthew  2585:             $count++;
1.35      matthew  2586:         } else {
1.88      matthew  2587:             $r->print(
                   2588:           &mt('Error dropping [_1]:[_2]',$uname.'@'.$udom,$result).
1.35      matthew  2589:                       '<br />');
                   2590:         }
1.20      harris41 2591:     }
1.88      matthew  2592:     $r->print('<p><b>'.&mt('Dropped [_1] student(s).',$count).'</b></p>');
                   2593:     $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count);
1.11      www      2594: }
                   2595: 
1.142     raeburn  2596: sub section_check_js {
                   2597:     my $groupslist;
1.143     raeburn  2598:     my %curr_groups = &Apache::longroup::coursegroups();
1.142     raeburn  2599:     if (%curr_groups) {
                   2600:         $groupslist = join('","',sort(keys(%curr_groups)));
                   2601:     }
                   2602:     return <<"END";
                   2603: function validate(caller) {
                   2604:     var groups = new Array("$groupslist");
                   2605:     var secname = caller.value;
                   2606:     if ((secname == 'all') || (secname == 'none')) {
                   2607:         alert("'"+secname+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
                   2608:         return 'error';
                   2609:     }
                   2610:     if (secname != '') {
                   2611:         for (var k=0; k<groups.length; k++) {
                   2612:             if (secname == groups[k]) {
                   2613:                 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.");
                   2614:                 return 'error';
                   2615:             }
                   2616:         }
                   2617:     }
                   2618:     return 'ok';
                   2619: }
                   2620: END
                   2621: }
                   2622: 
1.164     albertel 2623: sub get_permission {
                   2624:     my %permission;
                   2625:     $permission{'view'} = 
                   2626:         &Apache::lonnet::allowed('vcl',$env{'request.course.id'});
                   2627:     if (!$permission{'view'}) {
                   2628: 	my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'};
                   2629: 	$permission{'view'} =  &Apache::lonnet::allowed('vcl',$scope);
                   2630: 	if ($permission{'view'}) {
                   2631: 	    $permission{'view_section'} = $env{'request.course.sec'};
                   2632: 	}
                   2633:     }
                   2634: 
                   2635:     $permission{'enrl'} = 
                   2636:         &Apache::lonnet::allowed('cst',$env{'request.course.id'});
                   2637: 
                   2638:     $permission{'grp_view'} =
                   2639:         &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
                   2640:     $permission{'grp_manage'} =
                   2641:         &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
                   2642:     my $allowed = 0;
                   2643:     foreach my $perm (values(%permission)) {
                   2644: 	if ($perm) { $allowed=1; last; }
                   2645:     }
                   2646:     return (\%permission,$allowed);
                   2647: }
                   2648: 
1.50      matthew  2649: ###################################################################
                   2650: ###################################################################
                   2651: 
                   2652: =pod
                   2653: 
                   2654: =item &handler
                   2655: 
                   2656: The typical handler you see in all these modules.  Takes $r, the
                   2657: http request, as an argument.  
                   2658: 
                   2659: The response to the request is governed by two form variables
                   2660: 
                   2661:  form.action      form.state     response
                   2662:  ---------------------------------------------------
                   2663:  undefined        undefined      print main menu
                   2664:  upload           undefined      print courselist upload menu
                   2665:  upload           got_file       deal with uploaded file,
                   2666:                                  print the upload managing menu
                   2667:  upload           enrolling      enroll students based on upload
                   2668:  drop             undefined      print the classlist ready to drop
                   2669:  drop             done           drop the selected students
1.74      matthew  2670:  enrollstudent    undefined      print student username domain form
                   2671:  enrollstudent    gotusername    print single student enroll menu
1.50      matthew  2672:  enrollstudent    enrolling      enroll student
                   2673:  classlist        undefined      print html classlist
                   2674:  classlist        csv            print csv classlist
                   2675:  modifystudent    undefined      print classlist to select student to modify
                   2676:  modifystudent    selected       print modify student menu
                   2677:  modifystudent    done           make modifications to student record
                   2678: 
                   2679: =cut
                   2680: 
                   2681: ###################################################################
                   2682: ###################################################################
1.10      www      2683: sub handler {
1.26      matthew  2684:     my $r=shift;
                   2685:     if ($r->header_only) {
1.86      www      2686:         &Apache::loncommon::content_type($r,'text/html');
1.26      matthew  2687:         $r->send_http_header;
                   2688:         return OK;
                   2689:     }
1.48      matthew  2690:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.50      matthew  2691:                                             ['action','state']);
1.102     matthew  2692: 
                   2693:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   2694:     &Apache::lonhtmlcommon::add_breadcrumb
                   2695:         ({href=>"/adm/dropadd",
                   2696:           text=>"Enrollment Manager",
                   2697:           faq=>9,bug=>'Instructor Interface',});
1.26      matthew  2698:     #  Needs to be in a course
1.127     albertel 2699:     if (! ($env{'request.course.fn'})) {
1.121     matthew  2700:         # Not in a course
1.127     albertel 2701:         $env{'user.error.msg'}=
1.132     raeburn  2702:             "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ".
                   2703:                                   "or drop or add students";
1.50      matthew  2704:         return HTTP_NOT_ACCEPTABLE; 
                   2705:     }
                   2706:     #
1.132     raeburn  2707: 
1.164     albertel 2708:     my ($permission,$allowed) = &get_permission();
1.132     raeburn  2709: 
1.164     albertel 2710:     if (!$allowed) {
1.127     albertel 2711:         $env{'user.error.msg'}=
1.164     albertel 2712: 	    "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ".
                   2713: 	                         "or drop or add students";
1.132     raeburn  2714:         return HTTP_NOT_ACCEPTABLE;
1.121     matthew  2715:     }
1.132     raeburn  2716: 
1.121     matthew  2717:     #
1.50      matthew  2718:     # Only output the header information if they did not request csv format
                   2719:     #
1.103     matthew  2720:     # Start page
                   2721:     &Apache::loncommon::content_type($r,'text/html');
                   2722:     $r->send_http_header;
1.50      matthew  2723:     #
                   2724:     # Main switch on form.action and form.state, as appropriate
1.127     albertel 2725:     if (! exists($env{'form.action'})) {
1.166     raeburn  2726:         $r->print(&header());
1.141     albertel 2727:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.164     albertel 2728:         my $action = &print_main_menu($r,$permission);
                   2729:     } elsif ($env{'form.action'} eq 'upload' && $permission->{'enrl'}) {
1.166     raeburn  2730:         $r->print(&header());
1.102     matthew  2731:         &Apache::lonhtmlcommon::add_breadcrumb
                   2732:             ({href=>'/adm/dropadd?action=upload&state=',
1.106     matthew  2733:               text=>"Upload Classlist"});
1.141     albertel 2734:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Upload Classlist',
                   2735: 						      'Course_Create_Class_List'));
1.127     albertel 2736:         if (! exists($env{'form.state'})) {
1.50      matthew  2737:             &print_first_courselist_upload_form($r);            
1.127     albertel 2738:         } elsif ($env{'form.state'} eq 'got_file') {
1.50      matthew  2739:             &print_upload_manager_form($r);
1.127     albertel 2740:         } elsif ($env{'form.state'} eq 'enrolling') {
                   2741:             if ($env{'form.datatoken'}) {
1.26      matthew  2742:                 &upfile_drop_add($r);
1.50      matthew  2743:             } else {
                   2744:                 # Hmmm, this is an error
1.26      matthew  2745:             }
1.50      matthew  2746:         } else {
                   2747:             &print_first_courselist_upload_form($r);            
1.26      matthew  2748:         }
1.164     albertel 2749:     } elsif ($env{'form.action'} eq 'drop' && $permission->{'enrl'}) {
1.166     raeburn  2750:         $r->print(&header());
1.102     matthew  2751:         &Apache::lonhtmlcommon::add_breadcrumb
                   2752:             ({href=>'/adm/dropadd?action=drop',
1.106     matthew  2753:               text=>"Drop Students"});
1.141     albertel 2754:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students',
                   2755: 						      'Course_Drop_Student'));
1.127     albertel 2756:         if (! exists($env{'form.state'})) {
1.51      matthew  2757:             &print_drop_menu($r);
1.127     albertel 2758:         } elsif ($env{'form.state'} eq 'done') {
1.26      matthew  2759:             &drop_student_list($r);
1.50      matthew  2760:         } else {
1.55      matthew  2761:             &print_drop_menu($r);
1.26      matthew  2762:         }
1.164     albertel 2763:     } elsif ($env{'form.action'} eq 'enrollstudent' && $permission->{'enrl'}) {
1.166     raeburn  2764:         my @search = ('srchterm','srchby','srchin','srchtype','srchdomain');
                   2765:         my ($jsback,$elements) = &Apache::loncreateuser::crumb_utilities();
                   2766:         my $jscript = '<script type="text/javascript">'.$jsback.'</script>';
1.172     albertel 2767: 	&Apache::loncreateuser::restore_prev_selections();
                   2768: 	my $srch;
                   2769: 	foreach my $item (@search) {
                   2770: 	    $srch->{$item} = $env{'form.'.$item};
                   2771: 	}
                   2772: 
1.166     raeburn  2773:         if ($env{'form.state'} eq 'gotusername') {
                   2774:             if ($env{'form.phase'} eq 'get_user_info') {
                   2775:                 my ($currstate,$response,$forcenewuser,$results) =
                   2776:                     &Apache::loncreateuser::user_search_result($srch);
1.171     raeburn  2777:                 if ($env{'form.currstate'} eq 'modify') {
                   2778:                     $currstate = $env{'form.currstate'};
                   2779:                 }
1.166     raeburn  2780:                 if ($currstate eq 'select') {
                   2781:                     $r->print(&header());
                   2782:                     &Apache::lonhtmlcommon::add_breadcrumb
                   2783:                         ({href=>"javascript:backPage(document.usersrchform,'','')",
                   2784:                           text=>"Single user search"},
                   2785:                          {href=>"javascript:backPage(document.usersrchform,'get_user_info','select')",
                   2786:                           text=>"Select User",});
                   2787:                     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   2788:                                                                   'Course_Add_Student'));
                   2789:                     &Apache::loncreateuser::print_user_selection_page($r,
                   2790:                         $response,$srch,$results,'enrollstudent',\@search);
                   2791:                 } elsif ($currstate eq 'modify') {
                   2792:                     my ($ccuname,$ccdomain);
                   2793:                     if (($srch->{'srchby'} eq 'uname') &&
                   2794:                         ($srch->{'srchtype'} eq 'exact')) {
                   2795:                         $ccuname = $srch->{'srchterm'};
                   2796:                         $ccdomain= $srch->{'srchdomain'};
                   2797:                     } else {
                   2798:                         my @matchedunames = keys(%{$results});
                   2799:                         ($ccuname,$ccdomain) = split(/:/,$matchedunames[0]);
                   2800:                     }
                   2801:                     $ccuname =&LONCAPA::clean_username($ccuname);
                   2802:                     $ccdomain=&LONCAPA::clean_domain($ccdomain);
                   2803:                     &print_enroll_single_student_form($r,$jscript,$ccuname,
                   2804:                                                       $ccdomain,$srch,$response);
                   2805:                 } elsif ($currstate eq 'query') {
                   2806:                     $r->print(&header($jscript));
                   2807:                     &Apache::lonhtmlcommon::add_breadcrumb
                   2808:                         ({href=>"javascript:backPage(document.studentform,'','')",
                   2809:                           text=>"Single user search"});
                   2810:                     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   2811:                                                       'Course_Add_Student'));
                   2812:                     &Apache::loncreateuser::print_user_query_page($r,'enrollstudent');
                   2813:                 } else {
                   2814:                     &get_student_username_domain_form($r,$elements,$response,
                   2815:                                                       $srch,$forcenewuser);
                   2816:                 }
                   2817:             } elsif ($env{'form.phase'} eq 'userpicked') {
                   2818:                 my $ccuname = &LONCAPA::clean_username($env{'form.seluname'});
                   2819:                 my $ccdomain = &LONCAPA::clean_domain($env{'form.seludom'});
                   2820:                 &print_enroll_single_student_form($r,$jscript,$ccuname,
                   2821:                                                   $ccdomain,$srch);
                   2822:             } else {
1.172     albertel 2823:                 &get_student_username_domain_form($r,$elements,undef,$srch);
1.166     raeburn  2824:             }
1.127     albertel 2825:         } elsif ($env{'form.state'} eq 'enrolling') {
1.166     raeburn  2826:             $r->print(&header($jscript));
                   2827:             &Apache::lonhtmlcommon::add_breadcrumb
                   2828:                 ({href=>"javascript:backPage(document.studentform,'','')",
                   2829:                   text=>"Single user search"});
                   2830:             if ($env{'form.prevphase'} eq 'userpicked') {
                   2831:                &Apache::lonhtmlcommon::add_breadcrumb
                   2832:                ({href=>"javascript:backPage(document.studentform,'get_user_info','select')",
                   2833:                  text=>"Select user",});
                   2834:             }
                   2835:             &Apache::lonhtmlcommon::add_breadcrumb
                   2836:                 ({href=>"javascript:backPage(document.studentform,'$env{'form.prevphase'}','modify')",
                   2837:                   text=>"Set enrollment",},
                   2838:                  {href=>"javascript:backPage(document.studentform,$env{'form.phase'},'')",
                   2839:                  text=>"Result",});
                   2840:             $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
                   2841:                                                       'Course_Add_Student'));
                   2842:             &enroll_single_student($r,\@search);
1.50      matthew  2843:         } else {
1.172     albertel 2844:             &get_student_username_domain_form($r,$elements,undef,$srch);
1.26      matthew  2845:         }
1.164     albertel 2846:     } elsif ($env{'form.action'} eq 'classlist' && $permission->{'view'}) {
1.167     raeburn  2847:         $r->print(&header());
1.102     matthew  2848:         &Apache::lonhtmlcommon::add_breadcrumb
                   2849:             ({href=>'/adm/dropadd?action=classlist',
1.106     matthew  2850:               text=>"View Classlist"});
1.141     albertel 2851:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('View Classlist',
                   2852: 						      'Course_View_Class_List'));
1.127     albertel 2853:         if (! exists($env{'form.state'})) {
1.164     albertel 2854:             &print_html_classlist($r,undef,$permission);
1.127     albertel 2855:         } elsif ($env{'form.state'} eq 'csv') {
1.164     albertel 2856:             &print_html_classlist($r,'csv',$permission);
1.127     albertel 2857:         } elsif ($env{'form.state'} eq 'excel') {
1.164     albertel 2858:             &print_html_classlist($r,'excel',$permission);
1.50      matthew  2859:         } else {
1.164     albertel 2860:             &print_html_classlist($r,undef,$permission);
1.50      matthew  2861:         }
1.164     albertel 2862:     } elsif ($env{'form.action'} eq 'modifystudent' && $permission->{'enrl'}) {
1.167     raeburn  2863:         $r->print(&header());
1.102     matthew  2864:         &Apache::lonhtmlcommon::add_breadcrumb
                   2865:             ({href=>'/adm/dropadd?action=modifystudent',
1.106     matthew  2866:               text=>"Modify Student Data"});
1.141     albertel 2867:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Modify Student Data',
                   2868: 						      'Course_Modify_Student_Data'));
1.127     albertel 2869:         if (! exists($env{'form.state'})) {
1.164     albertel 2870:             &print_html_classlist($r,undef,$permission);
1.127     albertel 2871:         } elsif ($env{'form.state'} eq 'selected') {
1.50      matthew  2872:             &print_modify_student_form($r);
1.127     albertel 2873:         } elsif ($env{'form.state'} eq 'done') {
1.50      matthew  2874:             &modify_single_student($r);
                   2875:         } else {
1.164     albertel 2876:             &print_html_classlist($r,undef,$permission);
1.50      matthew  2877:         }        
                   2878:     } else {
                   2879:         # We should not end up here, but I guess it is possible
                   2880:         &Apache::lonnet::logthis("Undetermined state in londropadd.pm.  ".
1.127     albertel 2881:                                  "form.action = ".$env{'form.action'}.
1.50      matthew  2882:                                  "Someone should fix this.");
1.167     raeburn  2883:         $r->print(&header());
1.141     albertel 2884:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.164     albertel 2885:         &print_main_menu($r,$permission);
1.50      matthew  2886:     }
                   2887:     #
                   2888:     # Finish up
1.138     albertel 2889:     $r->print('</form>'.&Apache::loncommon::end_page());
1.26      matthew  2890:     return OK;
1.1       www      2891: }
                   2892: 
1.50      matthew  2893: ###################################################################
                   2894: ###################################################################
                   2895: 
1.1       www      2896: 1;
                   2897: __END__
1.50      matthew  2898: 
1.1       www      2899: 

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