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

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

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