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

1.1       www         1: # The LearningOnline Network with CAPA
                      2: # Handler to drop and add students in courses 
                      3: #
1.166   ! raeburn     4: # $Id: londropadd.pm,v 1.165 2007/07/26 23:56:35 albertel Exp $
1.17      albertel    5: #
                      6: # Copyright Michigan State University Board of Trustees
                      7: #
                      8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      9: #
                     10: # LON-CAPA is free software; you can redistribute it and/or modify
                     11: # it under the terms of the GNU General Public License as published by
                     12: # the Free Software Foundation; either version 2 of the License, or
                     13: # (at your option) any later version.
                     14: #
                     15: # LON-CAPA is distributed in the hope that it will be useful,
                     16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     18: # GNU General Public License for more details.
                     19: #
                     20: # You should have received a copy of the GNU General Public License
                     21: # along with LON-CAPA; if not, write to the Free Software
                     22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     23: #
                     24: # /home/httpd/html/adm/gpl.txt
                     25: #
                     26: # http://www.lon-capa.org/
                     27: #
1.1       www        28: #
1.50      matthew    29: ###############################################################
1.82      www        30: ##############################################################
1.1       www        31: 
                     32: package Apache::londropadd;
                     33: 
                     34: use strict;
1.127     albertel   35: use Apache::lonnet;
1.24      albertel   36: use Apache::loncommon();
1.50      matthew    37: use Apache::lonhtmlcommon();
1.1       www        38: use Apache::Constants qw(:common :http REDIRECT);
1.60      matthew    39: use Spreadsheet::WriteExcel;
1.110     matthew    40: use Apache::lonstathelpers();
1.86      www        41: use Apache::lonlocal;
1.143     raeburn    42: use Apache::longroup;
1.152     albertel   43: use LONCAPA();
1.1       www        44: 
1.50      matthew    45: ###############################################################
                     46: ###############################################################
1.10      www        47: sub header {
1.166   ! raeburn    48:     my ($jscript,$loaditems) = @_;
        !            49:     my $start_page;
        !            50:     if (ref($loaditems) eq 'HASH') {
        !            51:         $start_page=&Apache::loncommon::start_page('Enrollment Manager',$jscript,{'add_entries' => $loaditems,});
        !            52:     } else {
        !            53:         $start_page=&Apache::loncommon::start_page('Enrollment Manager',$jscript);
        !            54:     }
1.27      matthew    55:     return(<<ENDHEAD);
1.138     albertel   56: $start_page
1.40      matthew    57: <form method="post" enctype="multipart/form-data"  
                     58:       action="/adm/dropadd" name="studentform">
1.1       www        59: ENDHEAD
1.10      www        60: }
                     61: 
1.50      matthew    62: ###############################################################
                     63: ###############################################################
                     64: # Drop student from all sections of a course, except optional $csec
1.26      matthew    65: sub modifystudent {
1.33      matthew    66:     my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;
1.26      matthew    67:     # if $csec is undefined, drop the student from all the courses matching
                     68:     # this one.  If $csec is defined, drop them from all other sections of 
                     69:     # this course and add them to section $csec
1.151     albertel   70:     my $cdom = $env{'course.'.$courseid.'.domain'};
                     71:     my $cnum = $env{'course.'.$courseid.'.num'};
1.26      matthew    72:     my %roles = &Apache::lonnet::dump('roles',$udom,$unam);
                     73:     my ($tmp) = keys(%roles);
                     74:     # Bail out if we were unable to get the students roles
1.35      matthew    75:     return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.26      matthew    76:     # Go through the roles looking for enrollment in this course
1.35      matthew    77:     my $result = '';
1.26      matthew    78:     foreach my $course (keys(%roles)) {
1.150     albertel   79:         if ($course=~m{^/\Q$cdom\E/\Q$cnum\E(?:\/)*(?:\s+)*(\w+)*\_st$}) {
1.26      matthew    80:             # We are in this course
1.25      matthew    81:             my $section=$1;
1.150     albertel   82:             $section='' if ($course eq "/$cdom/$cnum".'_st');
1.87      matthew    83:             if (defined($csec) && $section eq $csec) {
1.71      matthew    84:                 $result .= 'ok:';
                     85:             } elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) {
1.27      matthew    86:                 my (undef,$end,$start)=split(/\_/,$roles{$course});
1.25      matthew    87:                 my $now=time;
1.143     raeburn    88:                 # if this is an active role
1.27      matthew    89:                 if (!($start && ($now<$start)) || !($end && ($now>$end))) {
1.25      matthew    90:                     my $reply=&Apache::lonnet::modifystudent
1.70      matthew    91:                         # dom  name  id mode pass     f     m     l     g
                     92:                         ($udom,$unam,'',  '',  '',undef,undef,undef,undef,
1.33      matthew    93:                          $section,time,undef,undef,$desiredhost);
1.35      matthew    94:                     $result .= $reply.':';
1.25      matthew    95:                 }
1.10      www        96:             }
                     97:         }
1.20      harris41   98:     }
1.35      matthew    99:     if ($result eq '') {
1.62      matthew   100:         $result = 'Unable to find section for this student';
1.37      matthew   101:     } else {
                    102:         $result =~ s/(ok:)+/ok/g;
1.35      matthew   103:     }
                    104:     return $result;
1.10      www       105: }
                    106: 
1.50      matthew   107: ###############################################################
                    108: ###############################################################
                    109: # build a domain and server selection form
1.31      matthew   110: sub domain_form {
                    111:     my ($defdom) = @_;
                    112:     # Set up domain and server selection forms
                    113:     #
                    114:     # Get the domains
1.156     albertel  115:     my @domains = &Apache::lonnet::all_domains();
1.31      matthew   116:     # build up the menu information to be passed to 
                    117:     # &Apache::loncommon::linked_select_forms
                    118:     my %select_menus;
                    119:     foreach my $dom (@domains) {
                    120:         # set up the text for this domain
                    121:         $select_menus{$dom}->{'text'}= $dom;
                    122:         # we want a choice of 'default' as the default in the second menu
                    123:         $select_menus{$dom}->{'default'}= 'default';
                    124:         $select_menus{$dom}->{'select2'}->{'default'} = 'default';
                    125:         # Now build up the other items in the second menu
1.157     albertel  126:         my %servers = &Apache::lonnet::get_servers($dom,'library');
1.31      matthew   127:         foreach my $server (keys(%servers)) {
                    128:             $select_menus{$dom}->{'select2'}->{$server} 
                    129:                                             = "$server $servers{$server}";
                    130:         }
                    131:     }
                    132:     my $result  = &Apache::loncommon::linked_select_forms
                    133:         ('studentform',' with home server ',$defdom,
                    134:          'lcdomain','lcserver',\%select_menus);
                    135:     return $result;
                    136: }
                    137: 
1.50      matthew   138: ###############################################################
                    139: ###############################################################
                    140: #  Menu Phase One
                    141: sub print_main_menu {
1.164     albertel  142:     my ($r,$permission)=@_;
1.121     matthew   143:     #
1.150     albertel  144:     my $cid =$env{'request.course.id'};
                    145:     my $cdom=$env{'course.'.$cid.'.domain'};
                    146:     my $cnum=$env{'course.'.$cid.'.num'};
1.121     matthew   147:     my @menu = 
                    148:         ( 
1.122     matthew   149:           { text => 'Upload a class list', 
1.121     matthew   150:             help => 'Course_Create_Class_List',
                    151:             action => 'upload',
1.164     albertel  152:             permission => $permission->{'enrl'},
1.121     matthew   153:             },
                    154:           { text => 'Enroll a single student', 
                    155:             help => 'Course_Add_Student',
                    156:             action => 'enrollstudent',
1.164     albertel  157:             permission => $permission->{'enrl'},
1.121     matthew   158:             },
                    159:           { text => 'Modify student data', 
                    160:             help => 'Course_Modify_Student_Data',
                    161:             action => 'modifystudent',
1.164     albertel  162:             permission => $permission->{'enrl'},
1.121     matthew   163:             },
                    164:           { text => 'View Class List', 
                    165:             help => 'Course_View_Class_List',
                    166:             action => 'classlist',
1.164     albertel  167:             permission => $permission->{'view'},
1.121     matthew   168:             },
                    169:           { text => 'Drop Students', 
                    170:             help => 'Course_Drop_Student',
                    171:             action => 'drop',
1.164     albertel  172:             permission => $permission->{'enrl'},
1.121     matthew   173:             },
                    174:           { text => 'Automated Enrollment Manager', 
1.164     albertel  175:             permission => (&Apache::lonnet::auto_run($cnum,$cdom) 
                    176: 			   && $permission->{'enrl'}),
1.121     matthew   177:             url  => '/adm/populate',
                    178:             },
1.145     albertel  179:           { text => 'Create a new group',
                    180:             help => 'Course_Create_Group',
1.164     albertel  181:             permission => $permission->{'grp_manage'},
1.145     albertel  182:             url => '/adm/coursegroups?refpage=enrl&action=create',
                    183:             },
                    184:           { text => 'Modify an existing group',
                    185:             help => 'Course_Modify_Group',
1.164     albertel  186:             permission => $permission->{'grp_manage'},
1.145     albertel  187:             url => '/adm/coursegroups?refpage=enrl&action=modify',
                    188:             },
1.153     raeburn   189:           { text => 'Delete an existing group',
                    190:             help => 'Course_Delete_Group',
1.164     albertel  191:             permission => $permission->{'grp_manage'},
1.153     raeburn   192:             url => '/adm/coursegroups?refpage=enrl&action=delete',
                    193:             },
                    194:           { text => 'Re-enable a deleted group',
                    195:             help => 'Course_Reenable_Group',
1.164     albertel  196:             permission => $permission->{'grp_manage'},
1.153     raeburn   197:             url => '/adm/coursegroups?refpage=enrl&action=reenable',
                    198:             },
1.145     albertel  199:           { text => 'Enter an existing group',
                    200:             help => 'Course_Display_Group',
1.164     albertel  201:             permission => $permission->{'grp_view'},
1.145     albertel  202:             url => '/adm/coursegroups?refpage=enrl&action=view',
                    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;
                   1560: 	foreach my $type ('critnotification', 'permanentemail',
                   1561: 			  'notification') {
                   1562: 	    if ($emails{$type} =~ /\S/) {
                   1563: 		$email = $emails{$type};
                   1564: 		last;
                   1565: 	    }
                   1566: 	}
                   1567: 
1.114     raeburn  1568:         if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
                   1569:             if (! defined($start) || $start == 0) {
                   1570:                 $start = &mt('none');
                   1571:             } else {
                   1572:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1573:             }
                   1574:             if (! defined($end) || $end == 0) {
                   1575:                 $end = &mt('none');
                   1576:             } else {
                   1577:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1578:             }
1.139     albertel 1579: 	    $r->print(&Apache::loncommon::start_data_table_row());
1.115     raeburn  1580:             if ($mode eq 'autoenroll') {
                   1581:                 my $lockedtype = $sdata->[$index{'lockedtype'}];
                   1582:                 $studentcount++;
                   1583:                 my $cellentry;
                   1584:                 if ($type eq 'auto') {
1.131     albertel 1585:                     $cellentry = '<b>'.&mt('auto').'</b>&nbsp;<label><input type="checkbox" name="chgauto" value="'.$username.':'.$domain.'" />&nbsp;Change</label>';
1.115     raeburn  1586:                     $autocount ++;
                   1587:                 } else {
1.131     albertel 1588:                     $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  1589:                     $manualcount ++;
                   1590:                     if ($lockedtype) {
1.131     albertel 1591:                         $cellentry .= '<label><input type="checkbox" name="unlockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Unlock').'</label>';
1.115     raeburn  1592:                         $unlockcount ++;
                   1593:                     } else {
1.131     albertel 1594:                         $cellentry .= '<label><input type="checkbox" name="lockchg" value="'.$username.':'.$domain.'" />&nbsp;'.&mt('Lock').'</label>';
1.115     raeburn  1595:                         $lockcount ++;
                   1596:                     }
1.118     raeburn  1597:                     $cellentry .= '</nobr></td></tr></table>';
1.115     raeburn  1598:                 }
                   1599:                 $r->print("<td>$cellentry<td>\n    ");
                   1600:             } else {
                   1601:                 $r->print("<td>".(++$studentcount)."</td><td>\n    ");
                   1602:             }
1.51      matthew  1603:             if ($linkto eq 'nothing') {
                   1604:                 $r->print($username);
                   1605:             } elsif ($linkto eq 'aboutme') {
                   1606:                 $r->print(&Apache::loncommon::aboutmewrapper($username,
                   1607:                                                              $username,
                   1608:                                                              $domain));
                   1609:             } elsif ($linkto eq 'modify') {
1.59      matthew  1610:                 $r->print('<a href="'.
                   1611:                           "javascript:document.studentform.sname.value='".
                   1612:                           $username.
                   1613:                           "';document.studentform.sdom.value='".$domain.
                   1614:                           "';document.studentform.state.value='selected".
                   1615:                           "';document.studentform.submit();".'">'.
1.53      matthew  1616:                           $username."</a>\n");
1.50      matthew  1617:             }
1.51      matthew  1618:             $r->print(<<"END");
1.50      matthew  1619:     </td>
1.51      matthew  1620:     <td>$domain</td>
                   1621:     <td>$id</td>
                   1622:     <td>$name</td>
                   1623:     <td>$section</td>
1.110     matthew  1624:     <td>$start</td>
                   1625:     <td>$end</td>
1.142     raeburn  1626:     <td>$active_groups</td>
1.163     albertel 1627:     <td>$email</td>
1.114     raeburn  1628: END
1.134     raeburn  1629:             if ($env{'course.'.$env{'request.course.id'}.
1.136     raeburn  1630: 			 '.internal.showphoto'}) {
1.134     raeburn  1631:                 if ($displayphotos eq 'on') {
1.135     albertel 1632:                     my $imgurl = 
                   1633: 			&Apache::lonnet::retrievestudentphoto($domain,
                   1634: 							      $username,'gif',
                   1635: 							      'thumbnail');
1.134     raeburn  1636:                 
                   1637:                     $r->print('    <td align="right"><a href="javascript:photowindow('."'".&Apache::lonnet::studentphoto($domain,$username,'jpg')."'".')"><img src="'.$imgurl.'" border="1"></a></td>');
                   1638:                 } else {
                   1639:                     $r->print('    <td>&nbsp;</td>  ');
                   1640:                 }
                   1641:             }
1.139     albertel 1642: 	    $r->print(&Apache::loncommon::end_data_table_row());
1.51      matthew  1643:         } elsif ($mode eq 'csv') {
1.103     matthew  1644:             next if (! defined($CSVfile));
1.51      matthew  1645:             # no need to bother with $linkto
1.114     raeburn  1646:             if (! defined($start) || $start == 0) {
                   1647:                 $start = &mt('none');
                   1648:             } else {
                   1649:                 $start = &Apache::lonlocal::locallocaltime($start);
                   1650:             }
                   1651:             if (! defined($end) || $end == 0) {
                   1652:                 $end = &mt('none');
                   1653:             } else {
                   1654:                 $end = &Apache::lonlocal::locallocaltime($end);
                   1655:             }
1.51      matthew  1656:             my @line = ();
1.110     matthew  1657:             foreach ($username,$domain,$id,$name,$section,$start,$end) {
1.51      matthew  1658:                 push @line,&Apache::loncommon::csv_translate($_);
1.58      matthew  1659:             }
                   1660:             if ($statusmode eq 'Any') {
                   1661:                 push @line,&Apache::loncommon::csv_translate($status);
1.41      matthew  1662:             }
1.142     raeburn  1663:             push @line,&Apache::loncommon::csv_translate($active_groups);
1.163     albertel 1664:             push @line,&Apache::loncommon::csv_translate($email);
1.103     matthew  1665:             print $CSVfile '"'.join('","',@line).'"'."\n";
1.60      matthew  1666:         } elsif ($mode eq 'excel') {
1.110     matthew  1667:             $excel_sheet->write($row,0,[$username,$domain,$id,
                   1668:                                           $name,$section]);
                   1669:             my $col = 5;
                   1670:             foreach my $time ($start,$end) {
1.129     matthew  1671:                 if (defined($time) && $time != 0) {
                   1672:                     $excel_sheet->write($row,$col++,
1.110     matthew  1673:                                    &Apache::lonstathelpers::calc_serial($time),
                   1674:                                     $format->{'date'});
1.129     matthew  1675:                 } else {
                   1676:                     $excel_sheet->write($row,$col++,'none');
                   1677:                 }                    
1.110     matthew  1678:             }
                   1679:             $excel_sheet->write($row,$col++,$status);
1.142     raeburn  1680:             $excel_sheet->write($row,$col++,$active_groups);
1.163     albertel 1681:             $excel_sheet->write($row,$col++,$email);
1.110     matthew  1682:             $row++;
1.40      matthew  1683:         }
                   1684:     }
1.114     raeburn  1685:     if ($mode eq 'view' || $mode eq 'html' || $mode eq 'autoenroll') {
1.139     albertel 1686: 	$r->print(&Apache::loncommon::end_data_table().'<br />');
1.60      matthew  1687:     } elsif ($mode eq 'excel') {
                   1688:         $excel_workbook->close();
                   1689:         $r->print('<p><a href="'.$excel_filename.'">'.
1.94      sakharuk 1690:                   &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
1.103     matthew  1691:     } elsif ($mode eq 'csv') {
                   1692:         close($CSVfile);
                   1693:         $r->print('<a href="'.$CSVfilename.'">'.
                   1694:                   &mt('Your CSV file').'</a> is ready for download.'.
                   1695:                   "\n");
                   1696:         $r->rflush();
1.60      matthew  1697:     }
1.114     raeburn  1698:     if ($mode eq 'autoenroll') {
1.115     raeburn  1699:         return ($studentcount,$autocount,$manualcount,$lockcount,$unlockcount);
1.114     raeburn  1700:     }
1.115     raeburn  1701:     return;
1.40      matthew  1702: }
                   1703: 
1.50      matthew  1704: 
                   1705: #
                   1706: # print out form for modification of a single students data
                   1707: #
                   1708: sub print_modify_student_form {
                   1709:     my $r = shift();
                   1710:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.59      matthew  1711:                                             ['sdom','sname']);    
1.127     albertel 1712:     my $sname  = $env{'form.sname'};
                   1713:     my $sdom   = $env{'form.sdom'};
                   1714:     my $sortby = $env{'form.sortby'};
1.50      matthew  1715:     # determine the students name information
                   1716:     my %info=&Apache::lonnet::get('environment',
                   1717:                                   ['firstname','middlename',
1.52      matthew  1718:                                    'lastname','generation','id'],
1.50      matthew  1719:                                   $sdom, $sname);
                   1720:     my ($tmp) = keys(%info);
                   1721:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94      sakharuk 1722:         $r->print('<font color="#ff0000" size="+2">'.&mt('Error').'</font>'.
1.50      matthew  1723:                   '<p>'.
1.94      sakharuk 1724:                   &mt('Unable to retrieve environment data for').' '.$sname.
                   1725:                   &mt('in domain').' '.$sdom.'</p><p>'.
1.138     albertel 1726:                   &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p>'.&Apache::loncommon::end_page());
1.50      matthew  1727:         return;
                   1728:     }
                   1729:     # determine the students starting and ending times and section
                   1730:     my ($starttime,$endtime,$section) = &get_enrollment_data($sname,$sdom);
1.87      matthew  1731:     if ($starttime =~ /^error/) {
1.94      sakharuk 1732:         $r->print('<h2>'&mt('Error').'</h2>');
1.87      matthew  1733:         $r->print('<p>'.$starttime.'</p>');
                   1734:         return;
                   1735:     }
1.101     matthew  1736:     #
1.50      matthew  1737:     # Deal with date forms
1.101     matthew  1738:     my $current_date_description = '';
                   1739:     my $textdate = '';
                   1740: 
                   1741:     if (! defined($starttime) || $starttime == 0) {
                   1742:         $current_date_description = &mt('Current Starting Date: not set').
                   1743:             '<br />';
                   1744:     } else {
                   1745:         $current_date_description = 
                   1746:             &mt('Current Starting Date: [_1]',
                   1747:                 &Apache::lonlocal::locallocaltime($starttime)).'<br />';
                   1748:     }
                   1749:     if (! defined($endtime) || $endtime == 0) {
                   1750:         $current_date_description.= &mt('Current Ending Date: not set').
                   1751:             '<br />';
                   1752:     } else {
                   1753:         $current_date_description.= 
                   1754:             &mt('Current Ending Date: [_1]',
                   1755:                 &Apache::lonlocal::locallocaltime($endtime)).'<br />';
                   1756: 
                   1757:     }
1.68      matthew  1758:     my $date_table = &date_setting_table($starttime,$endtime);
1.59      matthew  1759:     #
1.127     albertel 1760:     if (! exists($env{'form.Status'}) || 
1.147     albertel 1761:         $env{'form.Status'} !~ /^(Any|Expired|Active|Future)$/) {
1.127     albertel 1762:         $env{'form.Status'} = 'crap';
1.59      matthew  1763:     }
1.94      sakharuk 1764:     # Make sure student is enrolled in course
                   1765:     my %lt=&Apache::lonlocal::texthash(
                   1766: 	           'mef'   => "Modify Enrollment for",
                   1767:                    'odcc'  => "Only domain coordinators can change a users password.",
                   1768:                    'sn'    => "Student Name",
                   1769:                    'fn'    => "First",
                   1770:                    'mn'    => "Middle",
                   1771:                    'ln'    => "Last",
                   1772:                    'gen'   => "Generation",
                   1773:                    'sid'   => "Student ID",
                   1774:                    'disn'  => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
                   1775:                    'sec'   => "Section",
                   1776:                    'sm'    => "Submit Modifications",
                   1777: 				       );
1.142     raeburn  1778: # Check if section name is valid
                   1779:     my $section_check = &section_check_js();
                   1780:     $r->print(<<"END");
                   1781: <script type="text/javascript">
                   1782: $section_check
                   1783: function secverify(formname,caller) {
                   1784:     if (validate(caller) == "error") {
                   1785:         return;
                   1786:     } else {
                   1787:         formname.submit();
                   1788:     }
                   1789: }
                   1790: </script>
1.52      matthew  1791: <p>
                   1792: <font size="+1">
1.94      sakharuk 1793: $lt{'odcc'}
1.52      matthew  1794: </font>
                   1795: </p>
1.50      matthew  1796: <input type="hidden" name="slogin"  value="$sname"  />
                   1797: <input type="hidden" name="sdomain" value="$sdom" />
                   1798: <input type="hidden" name="action"  value="modifystudent" />
1.53      matthew  1799: <input type="hidden" name="state"   value="done" />
                   1800: <input type="hidden" name="sortby"  value="$sortby" />
1.127     albertel 1801: <input type="hidden" name="Status"  value="$env{'form.Status'}" />
1.94      sakharuk 1802: <h2>$lt{'mef'} $info{'firstname'} $info{'middlename'} 
1.162     albertel 1803: $info{'lastname'} $info{'generation'}, $sname:$sdom</h2>
1.50      matthew  1804: <p>
1.94      sakharuk 1805: <b>$lt{'sn'}</b>
1.50      matthew  1806: <table>
1.94      sakharuk 1807: <tr><th>$lt{'fn'}</th><th>$lt{'mn'}</th><th>$lt{'ln'}</th><th>$lt{'gen'}</th></tr>
1.50      matthew  1808: <tr><td>
                   1809: <input type="text" name="firstname"  value="$info{'firstname'}"  /></td><td>
                   1810: <input type="text" name="middlename" value="$info{'middlename'}" /></td><td>
                   1811: <input type="text" name="lastname"   value="$info{'lastname'}"   /></td><td>
                   1812: <input type="text" name="generation" value="$info{'generation'}" /></td></tr>
                   1813: </table>
                   1814: </p><p>
1.160     albertel 1815: <b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12" />
1.52      matthew  1816: </p><p>
1.131     albertel 1817: <label>
1.160     albertel 1818: <input type="checkbox" name="forceid" /> 
1.94      sakharuk 1819: $lt{'disn'}
1.131     albertel 1820: </label>
1.53      matthew  1821: </p><p>
1.160     albertel 1822: <b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="14" />
1.50      matthew  1823: </p>
1.101     matthew  1824: <p>$current_date_description</p>
1.68      matthew  1825: <p>$date_table</p>
1.142     raeburn  1826: <input type="button" value="$lt{'sm'}" onClick="secverify(this.form,this.form.section)" />
1.50      matthew  1827: END
1.138     albertel 1828:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  1829:     return;
                   1830: }
                   1831: 
                   1832: #
                   1833: # modify a single students section 
                   1834: #
                   1835: sub modify_single_student {
1.138     albertel 1836:     my ($r) = @_;
1.68      matthew  1837:     #
1.80      matthew  1838:     # Remove non alphanumeric values from the section
1.127     albertel 1839:     $env{'form.section'} =~ s/\W//g;
1.77      matthew  1840:     #
1.68      matthew  1841:     # Do the date defaults first
                   1842:     my ($starttime,$endtime) = &get_dates_from_form();
1.127     albertel 1843:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  1844:         $r->print(&make_dates_default($starttime,$endtime));
                   1845:     }
1.59      matthew  1846:     # Get the 'sortby' and 'Status' variables so the user goes back to their
                   1847:     # previous screen
1.127     albertel 1848:     my $sortby = $env{'form.sortby'};
                   1849:     my $status = $env{'form.Status'};
1.53      matthew  1850:     #
                   1851:     # We always need this information
1.127     albertel 1852:     my $slogin     = $env{'form.slogin'};
                   1853:     my $sdom       = $env{'form.sdomain'};
1.53      matthew  1854:     #
                   1855:     # Get the old data
                   1856:     my %old=&Apache::lonnet::get('environment',
                   1857:                                  ['firstname','middlename',
                   1858:                                   'lastname','generation','id'],
                   1859:                                  $sdom, $slogin);
1.59      matthew  1860:     $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin,
1.127     albertel 1861:                                                   $env{'request.course.id'});
1.53      matthew  1862:     my ($tmp) = keys(%old);
                   1863:     if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.162     albertel 1864:         $r->print(&mt('There was an error determining the environment values for')." $slogin : $sdom.");
1.53      matthew  1865:         return;
                   1866:     }
                   1867:     undef $tmp;
                   1868:     #
                   1869:     # Get the new data
1.127     albertel 1870:     my $firstname  = $env{'form.firstname'};
                   1871:     my $middlename = $env{'form.middlename'};
                   1872:     my $lastname   = $env{'form.lastname'};
                   1873:     my $generation = $env{'form.generation'};
                   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",
                   1898:                    'sec'   => "Section",
                   1899:                    'ri'    => "Role Information",
                   1900:                    'st'    => "Start Time",
                   1901:                    'et'    => "End Time",
                   1902: 				       );
1.50      matthew  1903:     $r->print(<<END);
1.162     albertel 1904:     <h2>$lt{'mdu'} $slogin : $sdom </h2>
1.94      sakharuk 1905: <h3>$lt{'si'}</h3>
1.53      matthew  1906: <table rules="rows" border="1" cellpadding="3" >
                   1907: <tr>
1.94      sakharuk 1908:     <th> $lt{'fd'} </th>
                   1909:     <th> $lt{'ov'} </th>
                   1910:     <th> $lt{'nv'} </th>
1.53      matthew  1911: </tr>
                   1912: <tr>
1.94      sakharuk 1913:     <td> <b>$lt{'fn'}</b> </td>
1.53      matthew  1914:     <td> $old{'firstname'} </td>
                   1915:     <td> $firstname </td>
                   1916: </tr><tr>
1.94      sakharuk 1917:     <td> <b>$lt{'mn'}</b> </td>
1.53      matthew  1918:     <td> $old{'middlename'} </td>
                   1919:     <td> $middlename </td>
                   1920: </tr><tr>
1.94      sakharuk 1921:     <td> <b>$lt{'ln'}</b> </td>
1.53      matthew  1922:     <td> $old{'lastname'} </td>
                   1923:     <td> $lastname </td>
                   1924: </tr><tr>
1.94      sakharuk 1925:     <td> <b>$lt{'gen'}</b> </td>
1.53      matthew  1926:     <td> $old{'generation'} </td>
                   1927:     <td> $generation </td>
                   1928: </tr><tr>
                   1929:     <td> <b>ID</b> </td>
                   1930:     <td> $old{'id'} </td>
                   1931:     <td> $sid </td>
1.59      matthew  1932: </tr><tr>
1.94      sakharuk 1933:     <td> <b>$lt{'sec'}</b> </td>
1.59      matthew  1934:     <td> $old{'section'} </td>
                   1935:     <td> $section</td>
1.53      matthew  1936: </tr>
1.50      matthew  1937: </table>
1.94      sakharuk 1938: <h3>$lt{'ri'}</h3>
1.50      matthew  1939: <table>
1.94      sakharuk 1940: <tr><td align="right"><b>$lt{'st'}:</b></td><td> $displayable_starttime </td></tr>
                   1941: <tr><td align="right"><b>$lt{'et'}:</b></td><td> $displayable_endtime   </td></tr>
1.50      matthew  1942: </table>
1.52      matthew  1943: <p>
1.50      matthew  1944: END
1.53      matthew  1945:     #
1.63      matthew  1946:     # Send request(s) to modify data (final undef is for 'desiredhost',
                   1947:     # which is a moot point because the student already has an account.
                   1948:     my $modify_section_results = &modifystudent($sdom,$slogin,
1.127     albertel 1949:                                                 $env{'request.course.id'},
1.63      matthew  1950:                                                 $section,undef);
                   1951:     if ($modify_section_results !~ /^ok/) {
1.94      sakharuk 1952:         $r->print(&mt('An error occured during the attempt to change the section for this student.')."<br />");
1.63      matthew  1953:     }
1.52      matthew  1954:     my $roleresults = &Apache::lonnet::modifystudent
1.53      matthew  1955:         ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname,
1.127     albertel 1956:          $generation,$section,$endtime,$starttime,$env{'form.forceid'});
1.53      matthew  1957:     if ($roleresults eq 'refused' ) {
1.94      sakharuk 1958:         $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  1959:     } elsif ($roleresults !~ /ok/) {
1.94      sakharuk 1960:         $r->print(&mt('An error occurred during the attempt to change the role information for this student.')."  <br />".
                   1961:                   &mt('The error reported was')." ".
1.50      matthew  1962:                   $roleresults);
1.53      matthew  1963:         &Apache::lonnet::logthis("londropadd:failed attempt to modify student".
1.162     albertel 1964:                                  " data for ".$slogin." : ".$sdom." by ".
                   1965:                                  $env{'user.name'}." : ".$env{'user.domain'}.
1.53      matthew  1966:                                  ":".$roleresults);
1.50      matthew  1967:     } else { # everything is okay!
1.94      sakharuk 1968:         $r->print(&mt('Student information updated successfully.')." <br />".
                   1969:                   &mt('The student must log out and log in again to see these changes.'));
1.50      matthew  1970:     }
1.94      sakharuk 1971:     my $Masd=&mt('Modify another students data');
1.50      matthew  1972:     $r->print(<<END);
1.52      matthew  1973: </p><p>
1.59      matthew  1974: <input type="hidden" name="action" value="modifystudent" />
                   1975: <input type="hidden" name="sortby" value="$sortby" />
                   1976: <input type="hidden" name="Status" value="$status" />
1.94      sakharuk 1977: <a href="javascript:document.studentform.submit();">$Masd</a>
1.50      matthew  1978: END
1.138     albertel 1979:     $r->print(&Apache::loncommon::end_page());
1.50      matthew  1980:     return;
                   1981: }
                   1982: 
                   1983: sub get_enrollment_data {
                   1984:     my ($sname,$sdomain) = @_;
1.127     albertel 1985:     my $courseid = $env{'request.course.id'};
1.151     albertel 1986:     my $cdom = $env{'course.'.$courseid.'.domain'};
                   1987:     my $cnum = $env{'course.'.$courseid.'.num'};
1.50      matthew  1988:     my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname);
                   1989:     my ($tmp) = keys(%roles);
                   1990:     # Bail out if we were unable to get the students roles
1.87      matthew  1991:     return ('error'.$tmp) if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.50      matthew  1992:     # Go through the roles looking for enrollment in this course
                   1993:     my ($end,$start) = (undef,undef);
                   1994:     my $section = '';
                   1995:     my $count = scalar(keys(%roles));
                   1996:     while (my ($course,$role) = each(%roles)) {
1.150     albertel 1997:         if ($course=~m{^/\Q$cdom\E/\Q$cnum\E/*\s*(\w+)*_st$} ) {
1.50      matthew  1998:             #
                   1999:             # Get active role
                   2000:             $section=$1;
                   2001:             (undef,$end,$start)=split(/\_/,$role);
                   2002:             my $now=time;
                   2003:             my $notactive=0;
                   2004:             if ($start) {
                   2005:                 if ($now<$start) { $notactive=1; }
                   2006:             }
                   2007:             if ($end) {
                   2008:                 if ($now>$end) { $notactive=1; }
                   2009:             } 
                   2010:             unless ($notactive) { return ($start,$end,$section); }
                   2011:         }
                   2012:     }
                   2013:     return ($start,$end,$section);
                   2014: }
                   2015: 
1.56      matthew  2016: #################################################
                   2017: #################################################
                   2018: 
                   2019: =pod
                   2020: 
                   2021: =item show_drop_list
                   2022: 
                   2023: Display a list of students to drop
                   2024: Inputs: 
                   2025: 
                   2026: =over 4
                   2027: 
                   2028: =item $r, Apache request
                   2029: 
                   2030: =item $classlist, hash pointer returned from loncoursedata::get_classlist();
                   2031: 
                   2032: =item $keylist, array pointer returned from loncoursedata::get_classlist() 
                   2033: which describes the order elements are stored in the %$classlist values.
                   2034: 
                   2035: =item $nosort, if true, sorting links are omitted.
                   2036: 
                   2037: =back
                   2038: 
                   2039: =cut
                   2040: 
                   2041: #################################################
                   2042: #################################################
1.11      www      2043: sub show_drop_list {
1.56      matthew  2044:     my ($r,$classlist,$keylist,$nosort)=@_;
1.127     albertel 2045:     my $cid=$env{'request.course.id'};
                   2046:     if (! exists($env{'form.sortby'})) {
1.59      matthew  2047:         &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                   2048:                                                 ['sortby']);
                   2049:     }
1.127     albertel 2050:     my $sortby = $env{'form.sortby'};
1.142     raeburn  2051:     if ($sortby !~ /^(username|domain|section|groups|fullname|id|start|end)$/) {
1.54      matthew  2052:         $sortby = 'username';
                   2053:     }
1.142     raeburn  2054:     my $cdom = $env{'course.'.$cid.'.domain'};
                   2055:     my $cnum = $env{'course.'.$cid,'.num'};
                   2056:     my ($classgroups) = &Apache::loncoursedata::get_group_memberships(
1.143     raeburn  2057:                                               $classlist,$keylist,$cdom,$cnum);
1.56      matthew  2058:     #
1.54      matthew  2059:     my $action = "drop";
                   2060:     $r->print(<<END);
                   2061: <input type="hidden" name="sortby" value="$sortby" />
                   2062: <input type="hidden" name="action" value="$action" />
1.50      matthew  2063: <input type="hidden" name="state"  value="done" />
1.32      matthew  2064: <script>
1.51      matthew  2065: function checkAll(field) {
1.32      matthew  2066:     for (i = 0; i < field.length; i++)
                   2067:         field[i].checked = true ;
                   2068: }
                   2069: 
1.51      matthew  2070: function uncheckAll(field) {
1.32      matthew  2071:     for (i = 0; i < field.length; i++)
                   2072:         field[i].checked = false ;
                   2073: }
                   2074: </script>
                   2075: <p>
1.26      matthew  2076: <input type="hidden" name="phase" value="four">
1.56      matthew  2077: END
                   2078: 
1.110     matthew  2079: my %lt=&Apache::lonlocal::texthash('usrn'   => "username",
                   2080:                                    'dom'    => "domain",
                   2081:                                    'sn'     => "student name",
                   2082:                                    'sec'    => "section",
                   2083:                                    'start'  => "start date",
                   2084:                                    'end'    => "end date",
1.142     raeburn  2085:                                    'groups' => "active groups",
1.110     matthew  2086:                                    );
1.56      matthew  2087:     if ($nosort) {
1.139     albertel 2088: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  2089:         $r->print(<<END);
                   2090: <tr>
                   2091:     <th>&nbsp;</th>
1.94      sakharuk 2092:     <th>$lt{'usrn'}</th>
                   2093:     <th>$lt{'dom'}</th>
1.56      matthew  2094:     <th>ID</th>
1.94      sakharuk 2095:     <th>$lt{'sn'}</th>
                   2096:     <th>$lt{'sec'}</th>
1.110     matthew  2097:     <th>$lt{'start'}</th>
                   2098:     <th>$lt{'end'}</th>
1.142     raeburn  2099:     <th>$lt{'groups'}</th>
1.56      matthew  2100: </tr>
                   2101: END
                   2102: 
                   2103:     } else  {
1.139     albertel 2104: 	$r->print(&Apache::loncommon::start_data_table());
1.56      matthew  2105:         $r->print(<<END);
1.54      matthew  2106: <tr><th>&nbsp;</th>
                   2107:     <th>
1.94      sakharuk 2108:        <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a>
1.54      matthew  2109:     </th><th>
1.94      sakharuk 2110:        <a href="/adm/dropadd?action=$action&sortby=domain">$lt{'dom'}</a>
1.54      matthew  2111:     </th><th>
                   2112:        <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
                   2113:     </th><th>
1.94      sakharuk 2114:        <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a>
1.54      matthew  2115:     </th><th>
1.94      sakharuk 2116:        <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a>
1.110     matthew  2117:     </th><th>
                   2118:        <a href="/adm/dropadd?action=$action&sortby=start">$lt{'start'}</a>
                   2119:     </th><th>
                   2120:        <a href="/adm/dropadd?action=$action&sortby=end">$lt{'end'}</a>
1.142     raeburn  2121:     </th><th>
                   2122:        <a href="/adm/dropadd?action=$action&sortby=groups">$lt{'groups'}</a>
1.54      matthew  2123:     </th>
                   2124: </tr>
1.26      matthew  2125: END
1.56      matthew  2126:     }
                   2127:     #
                   2128:     # Sort the students
                   2129:     my %index;
                   2130:     my $i;
                   2131:     foreach (@$keylist) {
                   2132:         $index{$_} = $i++;
                   2133:     }
1.142     raeburn  2134:     $index{'groups'} = scalar(@$keylist);
1.56      matthew  2135:     my $index  = $index{$sortby};
                   2136:     my $second = $index{'username'};
                   2137:     my $third  = $index{'domain'};
1.54      matthew  2138:     my @Sorted_Students = sort {
1.56      matthew  2139:         lc($classlist->{$a}->[$index])  cmp lc($classlist->{$b}->[$index])
                   2140:             ||
                   2141:         lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
                   2142:             ||
                   2143:         lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
                   2144:         } (keys(%$classlist));
1.54      matthew  2145:     foreach my $student (@Sorted_Students) {
1.52      matthew  2146:         my $error;
1.110     matthew  2147:         my $sdata = $classlist->{$student};
                   2148:         my $username = $sdata->[$index{'username'}];
                   2149:         my $domain   = $sdata->[$index{'domain'}];
                   2150:         my $section  = $sdata->[$index{'section'}];
                   2151:         my $name     = $sdata->[$index{'fullname'}];
                   2152:         my $id       = $sdata->[$index{'id'}];
                   2153:         my $start    = $sdata->[$index{'start'}];
                   2154:         my $end      = $sdata->[$index{'end'}];
1.142     raeburn  2155:         my $groups = $classgroups->{$student};
                   2156:         my $active_groups;
                   2157:         if (ref($groups->{active}) eq 'HASH') {
                   2158:             $active_groups = join(', ',keys(%{$groups->{'active'}}));
                   2159:         }
1.110     matthew  2160:         if (! defined($start) || $start == 0) {
                   2161:             $start = &mt('none');
                   2162:         } else {
                   2163:             $start = &Apache::lonlocal::locallocaltime($start);
                   2164:         }
                   2165:         if (! defined($end) || $end == 0) {
                   2166:             $end = &mt('none');
                   2167:         } else {
                   2168:             $end = &Apache::lonlocal::locallocaltime($end);
                   2169:         }
                   2170:         my $status   = $sdata->[$index{'status'}];
1.51      matthew  2171:         next if ($status ne 'Active');
                   2172:         #
1.139     albertel 2173:         $r->print(&Apache::loncommon::start_data_table_row());
1.51      matthew  2174:         $r->print(<<"END");
                   2175:     <td><input type="checkbox" name="droplist" value="$student"></td>
                   2176:     <td>$username</td>
                   2177:     <td>$domain</td>
                   2178:     <td>$id</td>
                   2179:     <td>$name</td>
                   2180:     <td>$section</td>
1.110     matthew  2181:     <td>$start</td>
                   2182:     <td>$end</td>
1.142     raeburn  2183:     <td>$active_groups</td>
1.26      matthew  2184: END
1.139     albertel 2185:         $r->print(&Apache::loncommon::end_data_table_row());
1.25      matthew  2186:     }
1.139     albertel 2187:     $r->print(&Apache::loncommon::end_data_table().'<br />');
1.111     matthew  2188:     %lt=&Apache::lonlocal::texthash(
1.94      sakharuk 2189: 	               'dp'   => "Drop Students",
                   2190:                        'ca'   => "check all",
                   2191:                        'ua'   => "uncheck all",
                   2192: 				       );
1.32      matthew  2193:     $r->print(<<"END");
                   2194: </p><p>
1.94      sakharuk 2195: <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)"> &nbsp;
                   2196: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)"> 
                   2197: <p><input type=submit value="$lt{'dp'}"></p>
1.32      matthew  2198: END
1.51      matthew  2199:     return;
1.10      www      2200: }
                   2201: 
1.48      matthew  2202: #
                   2203: # Print out the initial form to get the courselist file
                   2204: #
                   2205: sub print_first_courselist_upload_form {
                   2206:     my $r=shift;
1.88      matthew  2207:     my $str;
                   2208:     $str  = '<input type="hidden" name="phase" value="two">';
                   2209:     $str .= '<input type="hidden" name="action" value="upload" />';
                   2210:     $str .= '<input type="hidden"   name="state"  value="got_file" />';
                   2211:     $str .= "<h3>".&mt('Upload a class list')."</h3>\n";
                   2212:     $str .= &Apache::loncommon::upfile_select_html();
                   2213:     $str .= "<p>\n";
                   2214:     $str .= '<input type="submit" name="fileupload" value="'.
                   2215:         &mt('Upload class list').'">'."\n";
1.131     albertel 2216:     $str .= '<label><input type="checkbox" name="noFirstLine" /> '.
                   2217:         &mt('Ignore First Line')."</label></p>\n";
1.88      matthew  2218:     $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
1.92      sakharuk 2219:                          &mt("How do I create a class list from a spreadsheet")).
1.88      matthew  2220:                              "<br />\n";
                   2221:     $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
1.92      sakharuk 2222:                            &mt("How do I create a CSV file from a spreadsheet")).
1.88      matthew  2223:                                "<br />\n";
1.138     albertel 2224:     $str .= &Apache::loncommon::end_page();
1.88      matthew  2225:     $r->print($str);
1.48      matthew  2226:     return;
                   2227: }
                   2228: 
1.10      www      2229: # ================================================= Drop/Add from uploaded file
                   2230: sub upfile_drop_add {
                   2231:     my $r=shift;
1.24      albertel 2232:     &Apache::loncommon::load_tmp_file($r);
                   2233:     my @studentdata=&Apache::loncommon::upfile_record_sep();
1.127     albertel 2234:     if($env{'form.noFirstLine'}){shift(@studentdata);}
                   2235:     my @keyfields = split(/\,/,$env{'form.keyfields'});
                   2236:     my $cid = $env{'request.course.id'};
1.25      matthew  2237:     my %fields=();
1.127     albertel 2238:     for (my $i=0; $i<=$env{'form.nfields'}; $i++) {
                   2239:         if ($env{'form.upfile_associate'} eq 'reverse') {
                   2240:             if ($env{'form.f'.$i} ne 'none') {
                   2241:                 $fields{$keyfields[$i]}=$env{'form.f'.$i};
1.25      matthew  2242:             }
                   2243:         } else {
1.127     albertel 2244:             $fields{$env{'form.f'.$i}}=$keyfields[$i];
1.25      matthew  2245:         }
                   2246:     }
1.99      matthew  2247:     #
                   2248:     # Store the field choices away
                   2249:     foreach my $field (qw/username names 
                   2250:                        fname mname lname gen id sec ipwd email/) {
1.127     albertel 2251:         $env{'form.'.$field.'_choice'}=$fields{$field};
1.99      matthew  2252:     }
                   2253:     &Apache::loncommon::store_course_settings('enrollment_upload',
                   2254:                                               { 'username_choice' => 'scalar',
                   2255:                                                 'names_choice' => 'scalar',
                   2256:                                                 'fname_choice' => 'scalar',
                   2257:                                                 'mname_choice' => 'scalar',
                   2258:                                                 'lname_choice' => 'scalar',
                   2259:                                                 'gen_choice' => 'scalar',
                   2260:                                                 'id_choice' => 'scalar',
                   2261:                                                 'sec_choice' => 'scalar',
                   2262:                                                 'ipwd_choice' => 'scalar',
                   2263:                                                 'email_choice' => 'scalar' });
                   2264: 
1.26      matthew  2265:     #
1.68      matthew  2266:     my ($startdate,$enddate) = &get_dates_from_form();
1.127     albertel 2267:     if ($env{'form.makedatesdefault'}) {
1.68      matthew  2268:         $r->print(&make_dates_default($startdate,$enddate));
                   2269:     }
1.31      matthew  2270:     # Determine domain and desired host (home server)
1.127     albertel 2271:     my $domain=$env{'form.lcdomain'};
                   2272:     my $desiredhost = $env{'form.lcserver'};
1.31      matthew  2273:     if (lc($desiredhost) eq 'default') {
                   2274:         $desiredhost = undef;
                   2275:     } else {
1.157     albertel 2276:         my %home_servers = &Apache::lonnet::get_servers($domain,'library');
1.31      matthew  2277:         if (! exists($home_servers{$desiredhost})) {
1.88      matthew  2278:             $r->print('<font color="#ff0000">'.&mt('Error').'</font>'.
                   2279:                       &mt('Invalid home server specified'));
1.138     albertel 2280:             $r->print(&Apache::loncommon::end_page());
1.31      matthew  2281:             return;
                   2282:         }
                   2283:     }
1.26      matthew  2284:     # Determine authentication mechanism
                   2285:     my $amode  = '';
                   2286:     my $genpwd = '';
1.127     albertel 2287:     if ($env{'form.login'} eq 'krb') {
1.47      albertel 2288:         $amode='krb';
1.127     albertel 2289: 	$amode.=$env{'form.krbver'};
                   2290:         $genpwd=$env{'form.krbarg'};
                   2291:     } elsif ($env{'form.login'} eq 'int') {
1.25      matthew  2292:         $amode='internal';
1.127     albertel 2293:         if ((defined($env{'form.intarg'})) && ($env{'form.intarg'})) {
                   2294:             $genpwd=$env{'form.intarg'};
1.25      matthew  2295:         }
1.127     albertel 2296:     } elsif ($env{'form.login'} eq 'loc') {
1.25      matthew  2297:         $amode='localauth';
1.127     albertel 2298:         if ((defined($env{'form.locarg'})) && ($env{'form.locarg'})) {
                   2299:             $genpwd=$env{'form.locarg'};
1.79      matthew  2300:         }
                   2301:     }
                   2302:     if ($amode =~ /^krb/) {
                   2303:         if (! defined($genpwd) || $genpwd eq '') {
                   2304:             $r->print('<font color="red" size="+1">'.
1.88      matthew  2305:                       &mt('Unable to enroll students').'</font>  '.
                   2306:                       &mt('No Kerberos domain was specified.').'</p>');
1.79      matthew  2307:             $amode = ''; # This causes the loop below to be skipped
1.25      matthew  2308:         }
                   2309:     }
1.154     raeburn  2310:     if ( $domain eq &LONCAPA::clean_domain($domain)
1.150     albertel 2311: 	&& ($amode ne '')) {
1.26      matthew  2312:         #######################################
                   2313:         ##         Enroll Students           ##
                   2314:         #######################################
1.88      matthew  2315:         $r->print('<h3>'.&mt('Enrolling Students')."</h3>\n<p>\n");
1.25      matthew  2316:         my $count=0;
                   2317:         my $flushc=0;
                   2318:         my %student=();
1.142     raeburn  2319:         # Get information about course groups
1.143     raeburn  2320:         my %curr_groups = &Apache::longroup::coursegroups();
1.26      matthew  2321:         # Get new classlist
1.25      matthew  2322:         foreach (@studentdata) {
                   2323:             my %entries=&Apache::loncommon::record_sep($_);
1.26      matthew  2324:             # Determine student name
1.25      matthew  2325:             unless (($entries{$fields{'username'}} eq '') ||
                   2326:                     (!defined($entries{$fields{'username'}}))) {
1.26      matthew  2327:                 my ($fname, $mname, $lname,$gen) = ('','','','');
1.25      matthew  2328:                 if (defined($fields{'names'})) {
1.26      matthew  2329:                     ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
                   2330:                                             /([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.25      matthew  2331:                 } else {
                   2332:                     if (defined($fields{'fname'})) {
                   2333:                         $fname=$entries{$fields{'fname'}};
                   2334:                     }
                   2335:                     if (defined($fields{'mname'})) {
                   2336:                         $mname=$entries{$fields{'mname'}};
                   2337:                     }
                   2338:                     if (defined($fields{'lname'})) {
                   2339:                         $lname=$entries{$fields{'lname'}};
                   2340:                     }
                   2341:                     if (defined($fields{'gen'})) {
                   2342:                         $gen=$entries{$fields{'gen'}};
                   2343:                     }
                   2344:                 }
1.150     albertel 2345:                 if ($entries{$fields{'username'}}
                   2346: 		    ne &LONCAPA::clean_username($entries{$fields{'username'}})) {
1.88      matthew  2347:                     $r->print('<br />'.
                   2348:       &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
                   2349:           $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
                   2350:                               '</b>');
1.25      matthew  2351:                 } else {
1.26      matthew  2352:                     # determine section number
1.25      matthew  2353:                     my $sec='';
                   2354:                     my $username=$entries{$fields{'username'}};
                   2355:                     if (defined($fields{'sec'})) {
                   2356:                         if (defined($entries{$fields{'sec'}})) {
                   2357:                             $sec=$entries{$fields{'sec'}};
                   2358:                         }
                   2359:                     }
1.80      matthew  2360:                     # remove non alphanumeric values from section
                   2361:                     $sec =~ s/\W//g;
1.142     raeburn  2362:                     if ($sec eq "none" || $sec eq 'all') {
                   2363:                         $r->print('<br />'.
                   2364:       &mt('<b>[_1]</b>: Unable to enroll: section name "[_2]" for user [_3] [_4] [_5] [_6] is a reserved word.',
                   2365:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2366:                         next;
                   2367:                     } elsif (($sec ne '') && (exists($curr_groups{$sec}))) {
                   2368:                         $r->print('<br />'.
                   2369:       &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.',
                   2370:                         $username,$sec,$fname,$mname,$lname,$gen));
                   2371:                         next;
                   2372:                     }
1.26      matthew  2373:                     # determine student id number
1.25      matthew  2374:                     my $id='';
                   2375:                     if (defined($fields{'id'})) {
                   2376:                         if (defined($entries{$fields{'id'}})) {
                   2377:                             $id=$entries{$fields{'id'}};
                   2378:                         }
                   2379:                         $id=~tr/A-Z/a-z/;
                   2380:                     }
1.73      www      2381:                     # determine email address
                   2382:                     my $email='';
                   2383:                     if (defined($fields{'email'})) {
                   2384:                         if (defined($entries{$fields{'email'}})) {
                   2385:                             $email=$entries{$fields{'email'}};
                   2386:                             unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
                   2387:                         }
                   2388:                     }
1.26      matthew  2389:                     # determine student password
1.25      matthew  2390:                     my $password='';
                   2391:                     if ($genpwd) { 
                   2392:                         $password=$genpwd; 
                   2393:                     } else {
                   2394:                         if (defined($fields{'ipwd'})) {
                   2395:                             if ($entries{$fields{'ipwd'}}) {
                   2396:                                 $password=$entries{$fields{'ipwd'}};
                   2397:                             }
                   2398:                         }
                   2399:                     }
1.56      matthew  2400:                     # Clean up whitespace
                   2401:                     foreach (\$domain,\$username,\$id,\$fname,\$mname,
                   2402:                              \$lname,\$gen,\$sec) {
                   2403:                         $$_ =~ s/(\s+$|^\s+)//g;
                   2404:                     }
1.127     albertel 2405:                     if ($password || $env{'form.login'} eq 'loc') {
1.33      matthew  2406:                         &modifystudent($domain,$username,$cid,$sec,
                   2407:                                        $desiredhost);
1.25      matthew  2408:                         my $reply=&Apache::lonnet::modifystudent
                   2409:                             ($domain,$username,$id,$amode,$password,
                   2410:                              $fname,$mname,$lname,$gen,$sec,$enddate,
1.127     albertel 2411:                              $startdate,$env{'form.forceid'},$desiredhost,
1.73      www      2412:                              $email);
1.26      matthew  2413:                         if ($reply ne 'ok') {
1.72      matthew  2414:                             $reply =~ s/^error://;
1.88      matthew  2415:                             $r->print('<br />'.
                   2416:                 &mt('<b>[_1]</b>:  Unable to enroll: [_2]',$username,$reply));
1.10      www      2417:          		} else {
1.7       www      2418:                             $count++; $flushc++;
                   2419:                             $student{$username}=1;
1.6       www      2420:                             $r->print('. ');
1.7       www      2421:                             if ($flushc>15) {
                   2422: 				$r->rflush;
                   2423:                                 $flushc=0;
                   2424:                             }
1.6       www      2425:                         }
1.25      matthew  2426:                     } else {
1.88      matthew  2427:                         $r->print('<br />'.
                   2428:       &mt('<b>[_1]</b>: Unable to enroll.  No password specified.',$username)
                   2429:                                   );
1.25      matthew  2430:                     }
                   2431:                 }
1.26      matthew  2432:             }
                   2433:         } # end of foreach (@studentdata)
1.88      matthew  2434:         $r->print("</p>\n<p>\n".&mt('Processed [_1] student(s).',$count).
                   2435:                   "</p>\n");
                   2436:         $r->print("<p>\n".
                   2437:                   &mt('If active, the new role will be available when the '.
                   2438:                   'students next log in to LON-CAPA.')."</p>\n");
1.26      matthew  2439:         #####################################
                   2440:         #           Drop students           #
                   2441:         #####################################
1.127     albertel 2442:         if ($env{'form.fullup'} eq 'yes') {
1.88      matthew  2443:             $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");
1.26      matthew  2444:             #  Get current classlist
1.56      matthew  2445:             my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
                   2446:             if (! defined($classlist)) {
1.88      matthew  2447:                 $r->print(&mt('There are no students currently enrolled.').
                   2448:                           "\n");
1.56      matthew  2449:             } else {
                   2450:                 # Remove the students we just added from the list of students.
1.25      matthew  2451:                 foreach (@studentdata) {
                   2452:                     my %entries=&Apache::loncommon::record_sep($_);
                   2453:                     unless (($entries{$fields{'username'}} eq '') ||
                   2454:                             (!defined($entries{$fields{'username'}}))) {
1.56      matthew  2455:                         delete($classlist->{$entries{$fields{'username'}}.
1.26      matthew  2456:                                                 ':'.$domain});
1.25      matthew  2457:                     }
                   2458:                 }
1.56      matthew  2459:                 # Print out list of dropped students.
                   2460:                 &show_drop_list($r,$classlist,$keylist,'nosort');
1.25      matthew  2461:             }
                   2462:         }
1.26      matthew  2463:     } # end of unless
1.10      www      2464: }
                   2465: 
1.11      www      2466: # ================================================================== Phase four
                   2467: sub drop_student_list {
                   2468:     my $r=shift;
                   2469:     my $count=0;
1.128     albertel 2470:     my @droplist = &Apache::loncommon::get_env_multiple('form.droplist');
1.35      matthew  2471:     foreach (@droplist) {
1.26      matthew  2472:         my ($uname,$udom)=split(/\:/,$_);
1.56      matthew  2473:         # drop student
1.127     albertel 2474:         my $result = &modifystudent($udom,$uname,$env{'request.course.id'});
1.37      matthew  2475:         if ($result eq 'ok' || $result eq 'ok:') {
1.88      matthew  2476:             $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>');
1.59      matthew  2477:             $count++;
1.35      matthew  2478:         } else {
1.88      matthew  2479:             $r->print(
                   2480:           &mt('Error dropping [_1]:[_2]',$uname.'@'.$udom,$result).
1.35      matthew  2481:                       '<br />');
                   2482:         }
1.20      harris41 2483:     }
1.88      matthew  2484:     $r->print('<p><b>'.&mt('Dropped [_1] student(s).',$count).'</b></p>');
                   2485:     $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count);
1.11      www      2486: }
                   2487: 
1.142     raeburn  2488: sub section_check_js {
                   2489:     my $groupslist;
1.143     raeburn  2490:     my %curr_groups = &Apache::longroup::coursegroups();
1.142     raeburn  2491:     if (%curr_groups) {
                   2492:         $groupslist = join('","',sort(keys(%curr_groups)));
                   2493:     }
                   2494:     return <<"END";
                   2495: function validate(caller) {
                   2496:     var groups = new Array("$groupslist");
                   2497:     var secname = caller.value;
                   2498:     if ((secname == 'all') || (secname == 'none')) {
                   2499:         alert("'"+secname+"' may not be used as the name for a section, as it is a reserved word.\\nPlease choose a different section name.");
                   2500:         return 'error';
                   2501:     }
                   2502:     if (secname != '') {
                   2503:         for (var k=0; k<groups.length; k++) {
                   2504:             if (secname == groups[k]) {
                   2505:                 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.");
                   2506:                 return 'error';
                   2507:             }
                   2508:         }
                   2509:     }
                   2510:     return 'ok';
                   2511: }
                   2512: END
                   2513: }
                   2514: 
1.164     albertel 2515: sub get_permission {
                   2516:     my %permission;
                   2517:     $permission{'view'} = 
                   2518:         &Apache::lonnet::allowed('vcl',$env{'request.course.id'});
                   2519:     if (!$permission{'view'}) {
                   2520: 	my $scope = $env{'request.course.id'}.'/'.$env{'request.course.sec'};
                   2521: 	$permission{'view'} =  &Apache::lonnet::allowed('vcl',$scope);
                   2522: 	if ($permission{'view'}) {
                   2523: 	    $permission{'view_section'} = $env{'request.course.sec'};
                   2524: 	}
                   2525:     }
                   2526: 
                   2527:     $permission{'enrl'} = 
                   2528:         &Apache::lonnet::allowed('cst',$env{'request.course.id'});
                   2529: 
                   2530:     $permission{'grp_view'} =
                   2531:         &Apache::lonnet::allowed('vcg',$env{'request.course.id'});
                   2532:     $permission{'grp_manage'} =
                   2533:         &Apache::lonnet::allowed('mdg',$env{'request.course.id'});
                   2534:     my $allowed = 0;
                   2535:     foreach my $perm (values(%permission)) {
                   2536: 	if ($perm) { $allowed=1; last; }
                   2537:     }
                   2538:     return (\%permission,$allowed);
                   2539: }
                   2540: 
1.50      matthew  2541: ###################################################################
                   2542: ###################################################################
                   2543: 
                   2544: =pod
                   2545: 
                   2546: =item &handler
                   2547: 
                   2548: The typical handler you see in all these modules.  Takes $r, the
                   2549: http request, as an argument.  
                   2550: 
                   2551: The response to the request is governed by two form variables
                   2552: 
                   2553:  form.action      form.state     response
                   2554:  ---------------------------------------------------
                   2555:  undefined        undefined      print main menu
                   2556:  upload           undefined      print courselist upload menu
                   2557:  upload           got_file       deal with uploaded file,
                   2558:                                  print the upload managing menu
                   2559:  upload           enrolling      enroll students based on upload
                   2560:  drop             undefined      print the classlist ready to drop
                   2561:  drop             done           drop the selected students
1.74      matthew  2562:  enrollstudent    undefined      print student username domain form
                   2563:  enrollstudent    gotusername    print single student enroll menu
1.50      matthew  2564:  enrollstudent    enrolling      enroll student
                   2565:  classlist        undefined      print html classlist
                   2566:  classlist        csv            print csv classlist
                   2567:  modifystudent    undefined      print classlist to select student to modify
                   2568:  modifystudent    selected       print modify student menu
                   2569:  modifystudent    done           make modifications to student record
                   2570: 
                   2571: =cut
                   2572: 
                   2573: ###################################################################
                   2574: ###################################################################
1.10      www      2575: sub handler {
1.26      matthew  2576:     my $r=shift;
                   2577:     if ($r->header_only) {
1.86      www      2578:         &Apache::loncommon::content_type($r,'text/html');
1.26      matthew  2579:         $r->send_http_header;
                   2580:         return OK;
                   2581:     }
1.48      matthew  2582:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.50      matthew  2583:                                             ['action','state']);
1.102     matthew  2584: 
                   2585:     &Apache::lonhtmlcommon::clear_breadcrumbs();
                   2586:     &Apache::lonhtmlcommon::add_breadcrumb
                   2587:         ({href=>"/adm/dropadd",
                   2588:           text=>"Enrollment Manager",
                   2589:           faq=>9,bug=>'Instructor Interface',});
1.26      matthew  2590:     #  Needs to be in a course
1.127     albertel 2591:     if (! ($env{'request.course.fn'})) {
1.121     matthew  2592:         # Not in a course
1.127     albertel 2593:         $env{'user.error.msg'}=
1.132     raeburn  2594:             "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ".
                   2595:                                   "or drop or add students";
1.50      matthew  2596:         return HTTP_NOT_ACCEPTABLE; 
                   2597:     }
                   2598:     #
1.132     raeburn  2599: 
1.164     albertel 2600:     my ($permission,$allowed) = &get_permission();
1.132     raeburn  2601: 
1.164     albertel 2602:     if (!$allowed) {
1.127     albertel 2603:         $env{'user.error.msg'}=
1.164     albertel 2604: 	    "/adm/dropadd:cst:0:0:Cannot manage or view course groups, ".
                   2605: 	                         "or drop or add students";
1.132     raeburn  2606:         return HTTP_NOT_ACCEPTABLE;
1.121     matthew  2607:     }
1.132     raeburn  2608: 
1.121     matthew  2609:     #
1.50      matthew  2610:     # Only output the header information if they did not request csv format
                   2611:     #
1.103     matthew  2612:     # Start page
                   2613:     &Apache::loncommon::content_type($r,'text/html');
                   2614:     $r->send_http_header;
1.50      matthew  2615:     #
                   2616:     # Main switch on form.action and form.state, as appropriate
1.127     albertel 2617:     if (! exists($env{'form.action'})) {
1.166   ! raeburn  2618:         $r->print(&header());
1.141     albertel 2619:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.164     albertel 2620:         my $action = &print_main_menu($r,$permission);
                   2621:     } elsif ($env{'form.action'} eq 'upload' && $permission->{'enrl'}) {
1.166   ! raeburn  2622:         $r->print(&header());
1.102     matthew  2623:         &Apache::lonhtmlcommon::add_breadcrumb
                   2624:             ({href=>'/adm/dropadd?action=upload&state=',
1.106     matthew  2625:               text=>"Upload Classlist"});
1.141     albertel 2626:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Upload Classlist',
                   2627: 						      'Course_Create_Class_List'));
1.127     albertel 2628:         if (! exists($env{'form.state'})) {
1.50      matthew  2629:             &print_first_courselist_upload_form($r);            
1.127     albertel 2630:         } elsif ($env{'form.state'} eq 'got_file') {
1.50      matthew  2631:             &print_upload_manager_form($r);
1.127     albertel 2632:         } elsif ($env{'form.state'} eq 'enrolling') {
                   2633:             if ($env{'form.datatoken'}) {
1.26      matthew  2634:                 &upfile_drop_add($r);
1.50      matthew  2635:             } else {
                   2636:                 # Hmmm, this is an error
1.26      matthew  2637:             }
1.50      matthew  2638:         } else {
                   2639:             &print_first_courselist_upload_form($r);            
1.26      matthew  2640:         }
1.164     albertel 2641:     } elsif ($env{'form.action'} eq 'drop' && $permission->{'enrl'}) {
1.166   ! raeburn  2642:         $r->print(&header());
1.102     matthew  2643:         &Apache::lonhtmlcommon::add_breadcrumb
                   2644:             ({href=>'/adm/dropadd?action=drop',
1.106     matthew  2645:               text=>"Drop Students"});
1.141     albertel 2646:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Drop Students',
                   2647: 						      'Course_Drop_Student'));
1.127     albertel 2648:         if (! exists($env{'form.state'})) {
1.51      matthew  2649:             &print_drop_menu($r);
1.127     albertel 2650:         } elsif ($env{'form.state'} eq 'done') {
1.26      matthew  2651:             &drop_student_list($r);
1.50      matthew  2652:         } else {
1.55      matthew  2653:             &print_drop_menu($r);
1.26      matthew  2654:         }
1.164     albertel 2655:     } elsif ($env{'form.action'} eq 'enrollstudent' && $permission->{'enrl'}) {
1.166   ! raeburn  2656:         my @search = ('srchterm','srchby','srchin','srchtype','srchdomain');
        !          2657:         my ($jsback,$elements) = &Apache::loncreateuser::crumb_utilities();
        !          2658:         my $jscript = '<script type="text/javascript">'.$jsback.'</script>';
        !          2659:         if ($env{'form.state'} eq 'gotusername') {
        !          2660:             my $srch;
        !          2661:             foreach my $item (@search) {
        !          2662:                 $srch->{$item} = $env{'form.'.$item};
        !          2663:             }
        !          2664:             print STDERR "phase = $env{'form.phase'}\n";
        !          2665:             if ($env{'form.phase'} eq 'get_user_info') {
        !          2666:                 my ($currstate,$response,$forcenewuser,$results) =
        !          2667:                     &Apache::loncreateuser::user_search_result($srch);
        !          2668:                 if ($currstate eq 'select') {
        !          2669:                     $r->print(&header());
        !          2670:                     &Apache::lonhtmlcommon::add_breadcrumb
        !          2671:                         ({href=>"javascript:backPage(document.usersrchform,'','')",
        !          2672:                           text=>"Single user search"},
        !          2673:                          {href=>"javascript:backPage(document.usersrchform,'get_user_info','select')",
        !          2674:                           text=>"Select User",});
        !          2675:                     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
        !          2676:                                                                   'Course_Add_Student'));
        !          2677:                     &Apache::loncreateuser::print_user_selection_page($r,
        !          2678:                         $response,$srch,$results,'enrollstudent',\@search);
        !          2679:                 } elsif ($currstate eq 'modify') {
        !          2680:                     my ($ccuname,$ccdomain);
        !          2681:                     if (($srch->{'srchby'} eq 'uname') &&
        !          2682:                         ($srch->{'srchtype'} eq 'exact')) {
        !          2683:                         $ccuname = $srch->{'srchterm'};
        !          2684:                         $ccdomain= $srch->{'srchdomain'};
        !          2685:                     } else {
        !          2686:                         my @matchedunames = keys(%{$results});
        !          2687:                         ($ccuname,$ccdomain) = split(/:/,$matchedunames[0]);
        !          2688:                     }
        !          2689:                     $ccuname =&LONCAPA::clean_username($ccuname);
        !          2690:                     $ccdomain=&LONCAPA::clean_domain($ccdomain);
        !          2691:                     &print_enroll_single_student_form($r,$jscript,$ccuname,
        !          2692:                                                       $ccdomain,$srch,$response);
        !          2693:                 } elsif ($currstate eq 'query') {
        !          2694:                     $r->print(&header($jscript));
        !          2695:                     &Apache::lonhtmlcommon::add_breadcrumb
        !          2696:                         ({href=>"javascript:backPage(document.studentform,'','')",
        !          2697:                           text=>"Single user search"});
        !          2698:                     $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
        !          2699:                                                       'Course_Add_Student'));
        !          2700:                     &Apache::loncreateuser::print_user_query_page($r,'enrollstudent');
        !          2701:                 } else {
        !          2702:                     &get_student_username_domain_form($r,$elements,$response,
        !          2703:                                                       $srch,$forcenewuser);
        !          2704:                 }
        !          2705:             } elsif ($env{'form.phase'} eq 'userpicked') {
        !          2706:                 my $ccuname = &LONCAPA::clean_username($env{'form.seluname'});
        !          2707:                 my $ccdomain = &LONCAPA::clean_domain($env{'form.seludom'});
        !          2708:                 &print_enroll_single_student_form($r,$jscript,$ccuname,
        !          2709:                                                   $ccdomain,$srch);
        !          2710:             } else {
        !          2711:                 &get_student_username_domain_form($r,$elements);
        !          2712:             }
1.127     albertel 2713:         } elsif ($env{'form.state'} eq 'enrolling') {
1.166   ! raeburn  2714:             $r->print(&header($jscript));
        !          2715:             &Apache::lonhtmlcommon::add_breadcrumb
        !          2716:                 ({href=>"javascript:backPage(document.studentform,'','')",
        !          2717:                   text=>"Single user search"});
        !          2718:             if ($env{'form.prevphase'} eq 'userpicked') {
        !          2719:                &Apache::lonhtmlcommon::add_breadcrumb
        !          2720:                ({href=>"javascript:backPage(document.studentform,'get_user_info','select')",
        !          2721:                  text=>"Select user",});
        !          2722:             }
        !          2723:             &Apache::lonhtmlcommon::add_breadcrumb
        !          2724:                 ({href=>"javascript:backPage(document.studentform,'$env{'form.prevphase'}','modify')",
        !          2725:                   text=>"Set enrollment",},
        !          2726:                  {href=>"javascript:backPage(document.studentform,$env{'form.phase'},'')",
        !          2727:                  text=>"Result",});
        !          2728:             $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enroll Student',
        !          2729:                                                       'Course_Add_Student'));
        !          2730:             &enroll_single_student($r,\@search);
1.50      matthew  2731:         } else {
1.166   ! raeburn  2732:             &get_student_username_domain_form($r,$elements);
1.26      matthew  2733:         }
1.164     albertel 2734:     } elsif ($env{'form.action'} eq 'classlist' && $permission->{'view'}) {
1.102     matthew  2735:         &Apache::lonhtmlcommon::add_breadcrumb
                   2736:             ({href=>'/adm/dropadd?action=classlist',
1.106     matthew  2737:               text=>"View Classlist"});
1.141     albertel 2738:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('View Classlist',
                   2739: 						      'Course_View_Class_List'));
1.127     albertel 2740:         if (! exists($env{'form.state'})) {
1.164     albertel 2741:             &print_html_classlist($r,undef,$permission);
1.127     albertel 2742:         } elsif ($env{'form.state'} eq 'csv') {
1.164     albertel 2743:             &print_html_classlist($r,'csv',$permission);
1.127     albertel 2744:         } elsif ($env{'form.state'} eq 'excel') {
1.164     albertel 2745:             &print_html_classlist($r,'excel',$permission);
1.50      matthew  2746:         } else {
1.164     albertel 2747:             &print_html_classlist($r,undef,$permission);
1.50      matthew  2748:         }
1.164     albertel 2749:     } elsif ($env{'form.action'} eq 'modifystudent' && $permission->{'enrl'}) {
1.102     matthew  2750:         &Apache::lonhtmlcommon::add_breadcrumb
                   2751:             ({href=>'/adm/dropadd?action=modifystudent',
1.106     matthew  2752:               text=>"Modify Student Data"});
1.141     albertel 2753:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Modify Student Data',
                   2754: 						      'Course_Modify_Student_Data'));
1.127     albertel 2755:         if (! exists($env{'form.state'})) {
1.164     albertel 2756:             &print_html_classlist($r,undef,$permission);
1.127     albertel 2757:         } elsif ($env{'form.state'} eq 'selected') {
1.50      matthew  2758:             &print_modify_student_form($r);
1.127     albertel 2759:         } elsif ($env{'form.state'} eq 'done') {
1.50      matthew  2760:             &modify_single_student($r);
                   2761:         } else {
1.164     albertel 2762:             &print_html_classlist($r,undef,$permission);
1.50      matthew  2763:         }        
                   2764:     } else {
                   2765:         # We should not end up here, but I guess it is possible
                   2766:         &Apache::lonnet::logthis("Undetermined state in londropadd.pm.  ".
1.127     albertel 2767:                                  "form.action = ".$env{'form.action'}.
1.50      matthew  2768:                                  "Someone should fix this.");
1.141     albertel 2769:         $r->print(&Apache::lonhtmlcommon::breadcrumbs('Enrollment Manager'));
1.164     albertel 2770:         &print_main_menu($r,$permission);
1.50      matthew  2771:     }
                   2772:     #
                   2773:     # Finish up
1.138     albertel 2774:     $r->print('</form>'.&Apache::loncommon::end_page());
1.26      matthew  2775:     return OK;
1.1       www      2776: }
                   2777: 
1.50      matthew  2778: ###################################################################
                   2779: ###################################################################
                   2780: 
1.1       www      2781: 1;
                   2782: __END__
1.50      matthew  2783: 
1.1       www      2784: 

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