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

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

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