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

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

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