Annotation of loncom/interface/londropadd.pm, revision 1.96
1.1 www 1: # The LearningOnline Network with CAPA
2: # Handler to drop and add students in courses
3: #
1.96 ! raeburn 4: # $Id: londropadd.pm,v 1.95 2003/12/22 22:50:37 albertel Exp $
1.17 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
1.1 www 28: #
1.50 matthew 29: ###############################################################
1.82 www 30: ##############################################################
1.1 www 31:
32: package Apache::londropadd;
33:
34: use strict;
1.24 albertel 35: use Apache::lonnet();
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.86 www 40: use Apache::lonlocal;
1.1 www 41:
1.50 matthew 42: ###############################################################
43: ###############################################################
1.10 www 44: sub header {
1.46 www 45: my $bodytag=&Apache::loncommon::bodytag('Enrollment Manager');
1.88 matthew 46: my $title = &mt('LON-CAPA Enrollment Manager');
1.27 matthew 47: return(<<ENDHEAD);
1.1 www 48: <html>
49: <head>
1.88 matthew 50: <title>$title</title>
1.1 www 51: </head>
1.46 www 52: $bodytag
1.40 matthew 53: <form method="post" enctype="multipart/form-data"
54: action="/adm/dropadd" name="studentform">
1.1 www 55: ENDHEAD
1.10 www 56: }
57:
1.50 matthew 58: ###############################################################
59: ###############################################################
60: # Drop student from all sections of a course, except optional $csec
1.26 matthew 61: sub modifystudent {
1.33 matthew 62: my ($udom,$unam,$courseid,$csec,$desiredhost)=@_;
1.26 matthew 63: # if $csec is undefined, drop the student from all the courses matching
64: # this one. If $csec is defined, drop them from all other sections of
65: # this course and add them to section $csec
1.25 matthew 66: $courseid=~s/\_/\//g;
67: $courseid=~s/^(\w)/\/$1/;
1.26 matthew 68: my %roles = &Apache::lonnet::dump('roles',$udom,$unam);
69: my ($tmp) = keys(%roles);
70: # Bail out if we were unable to get the students roles
1.35 matthew 71: return "$1" if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.26 matthew 72: # Go through the roles looking for enrollment in this course
1.35 matthew 73: my $result = '';
1.26 matthew 74: foreach my $course (keys(%roles)) {
1.35 matthew 75: if ($course=~/^$courseid(?:\/)*(?:\s+)*(\w+)*\_st$/) {
1.26 matthew 76: # We are in this course
1.25 matthew 77: my $section=$1;
1.26 matthew 78: $section='' if ($course eq $courseid.'_st');
1.87 matthew 79: if (defined($csec) && $section eq $csec) {
1.71 matthew 80: $result .= 'ok:';
81: } elsif ( ((!$section) && (!$csec)) || ($section ne $csec) ) {
1.27 matthew 82: my (undef,$end,$start)=split(/\_/,$roles{$course});
1.25 matthew 83: my $now=time;
1.50 matthew 84: # if this is an active role
1.27 matthew 85: if (!($start && ($now<$start)) || !($end && ($now>$end))) {
1.25 matthew 86: my $reply=&Apache::lonnet::modifystudent
1.70 matthew 87: # dom name id mode pass f m l g
88: ($udom,$unam,'', '', '',undef,undef,undef,undef,
1.33 matthew 89: $section,time,undef,undef,$desiredhost);
1.35 matthew 90: $result .= $reply.':';
1.25 matthew 91: }
1.10 www 92: }
93: }
1.20 harris41 94: }
1.35 matthew 95: if ($result eq '') {
1.62 matthew 96: $result = 'Unable to find section for this student';
1.37 matthew 97: } else {
98: $result =~ s/(ok:)+/ok/g;
1.35 matthew 99: }
100: return $result;
1.10 www 101: }
102:
1.50 matthew 103: ###############################################################
104: ###############################################################
105: # build a domain and server selection form
1.31 matthew 106: sub domain_form {
107: my ($defdom) = @_;
108: # Set up domain and server selection forms
109: #
110: # Get the domains
111: my @domains = &Apache::loncommon::get_domains();
112: # build up the menu information to be passed to
113: # &Apache::loncommon::linked_select_forms
114: my %select_menus;
115: foreach my $dom (@domains) {
116: # set up the text for this domain
117: $select_menus{$dom}->{'text'}= $dom;
118: # we want a choice of 'default' as the default in the second menu
119: $select_menus{$dom}->{'default'}= 'default';
120: $select_menus{$dom}->{'select2'}->{'default'} = 'default';
121: # Now build up the other items in the second menu
1.45 matthew 122: my %servers = &Apache::loncommon::get_library_servers($dom);
1.31 matthew 123: foreach my $server (keys(%servers)) {
124: $select_menus{$dom}->{'select2'}->{$server}
125: = "$server $servers{$server}";
126: }
127: }
128: my $result = &Apache::loncommon::linked_select_forms
129: ('studentform',' with home server ',$defdom,
130: 'lcdomain','lcserver',\%select_menus);
131: return $result;
132: }
133:
1.50 matthew 134: ###############################################################
135: ###############################################################
136: # Menu Phase One
137: sub print_main_menu {
1.10 www 138: my $r=shift;
1.88 matthew 139: my %Text = &Apache::lonlocal::texthash
140: ('upload' => 'Upload a class list',
141: 'enrollone' => 'Enroll a single student',
142: 'modify' => 'Modify student data',
143: 'view' => 'View Class List',
1.91 raeburn 144: 'drop' => 'Drop Students',
145: 'populate' => 'Automated Enrollment Manager');
1.88 matthew 146:
1.48 matthew 147: $r->print(<<END);
148: <p>
1.50 matthew 149: <font size="+1">
1.88 matthew 150: <a href="/adm/dropadd?action=upload">$Text{'upload'}</a>
1.50 matthew 151: </font>
152: </p><p>
153: <font size="+1">
1.88 matthew 154: <a href="/adm/dropadd?action=enrollstudent">$Text{'enrollone'}</a>
1.50 matthew 155: </font>
1.48 matthew 156: </p><p>
1.50 matthew 157: <font size="+1">
1.88 matthew 158: <a href="/adm/dropadd?action=modifystudent">$Text{'modify'}</a>
1.50 matthew 159: </font>
1.48 matthew 160: </p><p>
1.50 matthew 161: <font size="+1">
1.88 matthew 162: <a href="/adm/dropadd?action=classlist">$Text{'view'}</a>
1.50 matthew 163: </font>
1.48 matthew 164: </p><p>
1.50 matthew 165: <font size="+1">
1.88 matthew 166: <a href="/adm/dropadd?action=drop">$Text{'drop'}</a>
1.50 matthew 167: </font>
1.91 raeburn 168: </p><p>
169: <font size="+1">
170: <a href="/adm/populate">$Text{'populate'}</a>
171: </font>
1.48 matthew 172: END
1.10 www 173: }
174:
1.50 matthew 175: ###############################################################
176: ###############################################################
1.89 matthew 177: sub hidden_input {
178: my ($name,$value) = @_;
179: return '<input type="hidden" name="'.$name.'" value="'.$value.'" />'."\n";
180: }
181:
1.50 matthew 182: sub print_upload_manager_header {
1.23 albertel 183: my ($r,$datatoken,$distotal,$krbdefdom)=@_;
1.24 albertel 184: my $javascript;
1.50 matthew 185: if (! exists($ENV{'form.upfile_associate'})) {
186: $ENV{'form.upfile_associate'} = 'forward';
187: }
188: if ($ENV{'form.associate'} eq 'Reverse Association') {
189: if ( $ENV{'form.upfile_associate'} ne 'reverse' ) {
190: $ENV{'form.upfile_associate'} = 'reverse';
191: } else {
192: $ENV{'form.upfile_associate'} = 'forward';
193: }
194: }
1.24 albertel 195: if ($ENV{'form.upfile_associate'} eq 'reverse') {
1.50 matthew 196: $javascript=&upload_manager_javascript_reverse_associate();
1.24 albertel 197: } else {
1.50 matthew 198: $javascript=&upload_manager_javascript_forward_associate();
1.24 albertel 199: }
1.89 matthew 200: my $javascript_validations=&javascript_validations('auth',$krbdefdom);
1.82 www 201: my $checked=(($ENV{'form.noFirstLine'})?' checked="1"':'');
1.88 matthew 202: $r->print('<h3>'.&mt('Uploading Class List')."</h3>\n".
203: "<hr>\n".
204: '<h3>'.&mt('Identify fields')."</h3>\n");
205: $r->print("<p>\n".
206: &mt('Total number of records found in file: [_1].',$distotal).
207: "\n".
208: "</p><hr>\n");
1.94 sakharuk 209: $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 210: $r->print(&hidden_input('action','upload').
211: &hidden_input('state','got_file').
212: &hidden_input('associate','').
213: &hidden_input('datatoken',$datatoken).
214: &hidden_input('fileupload',$ENV{'form.fileupload'}).
215: &hidden_input('upfiletype',$ENV{'form.upfiletype'}).
216: &hidden_input('upfile_associate',$ENV{'form.upfile_associate'}));
217: $r->print('<input type="button" value="Reverse Association" '.
218: 'name="'.&mt('Reverse Association').'" '.
219: 'onClick="javascript:this.form.associate.value=\'Reverse Association\';submit(this.form);" />');
220: $r->print('<input type="checkbox" name="noFirstLine" $checked />'.
221: &mt('Ignore First Line'));
222: $r->print("<hr />\n".
223: '<script type="text/javascript" language="Javascript">'."\n".
224: $javascript."\n".$javascript_validations.'</script>');
1.24 albertel 225: }
226:
1.50 matthew 227: ###############################################################
228: ###############################################################
1.24 albertel 229: sub javascript_validations {
1.96 ! raeburn 230: my ($mode,$krbdefdom,$curr_authtype,$curr_authfield)=@_;
1.89 matthew 231: my $authheader;
232: if ($mode eq 'auth') {
233: my %param = ( formname => 'studentform',
234: kerb_def_dom => $krbdefdom );
235: $authheader = &Apache::loncommon::authform_header(%param);
1.91 raeburn 236: } elsif ($mode eq 'createcourse') {
237: my %param = ( formname => 'ccrs',
238: kerb_def_dom => $krbdefdom );
239: $authheader = &Apache::loncommon::authform_header(%param);
1.96 ! raeburn 240: } elsif ($mode eq 'modifycourse') {
! 241: my %param = ( formname => 'cmod',
! 242: kerb_def_dom => $krbdefdom,
! 243: mode => 'modifycourse',
! 244: curr_authtype => $curr_authtype,
! 245: curr_autharg => $curr_authfield );
! 246: $authheader = &Apache::loncommon::authform_header(%param);
1.89 matthew 247: }
1.96 ! raeburn 248:
1.91 raeburn 249:
1.89 matthew 250: my %alert = &Apache::lonlocal::texthash
251: (username => 'You need to specify the username field.',
252: authen => 'You must choose an authentication type.',
253: krb => 'You need to specify the Kerberos domain.',
254: ipass => 'You need to specify the initial password.',
255: name => 'The optional name field was not specified.',
256: snum => 'The optional student number field was not specified.',
257: section => 'The optional section or group field was not specified.',
258: email => 'The optional email address field was not specified.',
259: continue => 'Continue enrollment?',
260: );
261:
262: # my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition();
263: my $function_name =(<<END);
1.73 www 264: function verify_message (vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail) {
1.89 matthew 265: END
266: my $auth_checks = (<<END);
1.3 www 267: var foundatype=0;
1.91 raeburn 268: END
1.96 ! raeburn 269: if ($mode eq 'createcourse') {
! 270: $auth_checks .= (<<END);
! 271: if (document.ccrs.autoadds[0].checked == true) {
! 272: if (current.radiovalue == null || current.radiovalue == 'nochange') {
! 273: alert('$alert{'authen'}');
! 274: return;
! 275: }
! 276: }
! 277: END
! 278: } else {
1.91 raeburn 279: $auth_checks .= (<<END);
1.3 www 280: if (founduname==0) {
1.89 matthew 281: alert('$alert{'username'}');
1.3 www 282: return;
283: }
1.61 matthew 284: // alert('current.radiovalue = '+current.radiovalue);
1.29 matthew 285: if (current.radiovalue == null || current.radiovalue == 'nochange') {
1.28 matthew 286: // They did not check any of the login radiobuttons.
1.89 matthew 287: alert('$alert{'authen'}');
1.28 matthew 288: return;
289: }
1.96 ! raeburn 290: END
! 291: }
! 292: if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
! 293: $auth_checks .= "
! 294: foundatype=1";
! 295: if ($mode eq 'createcourse') {
! 296: $auth_checks .= "
! 297: if ( (document.ccrs.autoadds[0].checked == true) &&
! 298: (document.ccrs.elements[current.argfield].value == null || document.ccrs.elements[current.argfield].value == '') ) {";
! 299: } elsif ($mode eq 'modifycourse') {
! 300: $auth_checks .= "
! 301: if (document.ccrs.elements[current.argfield].value == null || document.cmod.elements[current.argfield].value == '') }";
! 302: }
! 303: $auth_checks .= (<<END);
! 304: var alertmsg = '';
! 305: switch (current.radiovalue) {
! 306: case 'krb':
! 307: alertmsg = '$alert{'krb'}';
! 308: break;
! 309: default:
! 310: alertmsg = '';
! 311: }
! 312: if (alertmsg != '') {
! 313: alert(alertmsg);
! 314: return;
! 315: }
! 316: }
! 317: }
! 318: END
! 319: } else {
! 320: $auth_checks .= (<<END);
1.28 matthew 321: foundatype=1;
1.29 matthew 322: if (current.argfield == null || current.argfield == '') {
1.28 matthew 323: var alertmsg = '';
1.29 matthew 324: switch (current.value) {
1.28 matthew 325: case 'krb':
1.89 matthew 326: alertmsg = '$alert{'krb'}';
1.28 matthew 327: break;
328: case 'loc':
329: case 'fsys':
1.89 matthew 330: alertmsg = '$alert{'ipass'}';
1.28 matthew 331: break;
332: case 'fsys':
333: alertmsg = '';
334: break;
335: default:
336: alertmsg = '';
1.3 www 337: }
1.28 matthew 338: if (alertmsg != '') {
339: alert(alertmsg);
1.3 www 340: return;
341: }
342: }
1.89 matthew 343: END
1.96 ! raeburn 344: }
1.91 raeburn 345: my $optional_checks = '';
1.96 ! raeburn 346: if ( ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
1.91 raeburn 347: $optional_checks = (<<END);
348: vf.submit();
349: }
350: END
351: } else {
352: $optional_checks = (<<END);
1.89 matthew 353: var message='';
354: if (foundname==0) {
355: message='$alert{'name'}';
1.24 albertel 356: }
1.89 matthew 357: if (foundid==0) {
358: if (message!='') {
359: message+='\\n';
360: }
361: message+='$alert{'snum'}';
362: }
363: if (foundsec==0) {
364: if (message!='') {
365: message+='\\n';
366: }
367: message+='$alert{'section'}';
368: }
369: if (foundemail==0) {
370: if (message!='') {
371: message+='\\n';
372: }
373: message+='$alert{'email'}';
1.74 matthew 374: }
375: if (message!='') {
1.89 matthew 376: message+= '\\n$alert{'continue'}';
377: if (confirm(message)) {
378: vf.state.value='enrolling';
379: vf.submit();
380: }
1.74 matthew 381: } else {
1.89 matthew 382: vf.state.value='enrolling';
383: vf.submit();
1.74 matthew 384: }
385: }
1.89 matthew 386: END
1.91 raeburn 387: }
1.89 matthew 388: my $result = $function_name;
1.96 ! raeburn 389: if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
1.89 matthew 390: $result .= $auth_checks;
391: }
392: $result .= $optional_checks;
1.96 ! raeburn 393: if ( ($mode eq 'auth') || ($mode eq 'createcourse') || ($mode eq 'modifycourse') ) {
1.89 matthew 394: $result .= $authheader;
395: }
396: return $result;
1.74 matthew 397: }
398:
1.50 matthew 399: ###############################################################
400: ###############################################################
401: sub upload_manager_javascript_forward_associate {
1.24 albertel 402: return(<<ENDPICK);
403: function verify(vf) {
404: var founduname=0;
405: var foundpwd=0;
406: var foundname=0;
407: var foundid=0;
408: var foundsec=0;
1.73 www 409: var foundemail=0;
1.24 albertel 410: var tw;
411: for (i=0;i<=vf.nfields.value;i++) {
412: tw=eval('vf.f'+i+'.selectedIndex');
413: if (tw==1) { founduname=1; }
414: if ((tw>=2) && (tw<=6)) { foundname=1; }
415: if (tw==7) { foundid=1; }
416: if (tw==8) { foundsec=1; }
417: if (tw==9) { foundpwd=1; }
1.73 www 418: if (tw==10) { foundemail=1; }
1.24 albertel 419: }
1.73 www 420: verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec,foundemail);
1.24 albertel 421: }
422:
1.49 matthew 423: //
424: // vf = this.form
425: // tf = column number
426: //
427: // values of nw
428: //
429: // 0 = none
430: // 1 = username
431: // 2 = names (lastname, firstnames)
432: // 3 = fname (firstname)
433: // 4 = mname (middlename)
434: // 5 = lname (lastname)
435: // 6 = gen (generation)
436: // 7 = id
437: // 8 = section
438: // 9 = ipwd (password)
1.73 www 439: // 10 = email address
440:
1.24 albertel 441: function flip(vf,tf) {
442: var nw=eval('vf.f'+tf+'.selectedIndex');
443: var i;
1.49 matthew 444: // make sure no other columns are labeled the same as this one
1.24 albertel 445: for (i=0;i<=vf.nfields.value;i++) {
446: if ((i!=tf) && (eval('vf.f'+i+'.selectedIndex')==nw)) {
447: eval('vf.f'+i+'.selectedIndex=0;')
448: }
449: }
1.49 matthew 450: // If we set this to 'lastname, firstnames', clear out all the ones
451: // set to 'fname','mname','lname','gen' (3,4,5,6) currently.
1.24 albertel 452: if (nw==2) {
453: for (i=0;i<=vf.nfields.value;i++) {
454: if ((eval('vf.f'+i+'.selectedIndex')>=3) &&
455: (eval('vf.f'+i+'.selectedIndex')<=6)) {
456: eval('vf.f'+i+'.selectedIndex=0;')
457: }
458: }
459: }
1.49 matthew 460: // If we set this to one of 'fname','mname','lname','gen' (3,4,5,6),
461: // clear out any that are set to 'lastname, firstnames' (2)
1.24 albertel 462: if ((nw>=3) && (nw<=6)) {
463: for (i=0;i<=vf.nfields.value;i++) {
464: if (eval('vf.f'+i+'.selectedIndex')==2) {
465: eval('vf.f'+i+'.selectedIndex=0;')
466: }
467: }
468: }
1.49 matthew 469: // If we set the password, make the password form below correspond to
470: // the new value.
1.24 albertel 471: if (nw==9) {
1.28 matthew 472: changed_radio('int',document.studentform);
473: set_auth_radio_buttons('int',document.studentform);
474: vf.intarg.value='';
475: vf.krbarg.value='';
1.24 albertel 476: vf.locarg.value='';
477: }
478: }
479:
480: function clearpwd(vf) {
481: var i;
482: for (i=0;i<=vf.nfields.value;i++) {
483: if (eval('vf.f'+i+'.selectedIndex')==9) {
484: eval('vf.f'+i+'.selectedIndex=0;')
485: }
486: }
487: }
488:
489: ENDPICK
490: }
491:
1.50 matthew 492: ###############################################################
493: ###############################################################
494: sub upload_manager_javascript_reverse_associate {
1.24 albertel 495: return(<<ENDPICK);
496: function verify(vf) {
497: var founduname=0;
498: var foundpwd=0;
499: var foundname=0;
500: var foundid=0;
501: var foundsec=0;
502: var tw;
503: for (i=0;i<=vf.nfields.value;i++) {
504: tw=eval('vf.f'+i+'.selectedIndex');
505: if (i==0 && tw!=0) { founduname=1; }
506: if (((i>=1) && (i<=5)) && tw!=0 ) { foundname=1; }
507: if (i==6 && tw!=0) { foundid=1; }
508: if (i==7 && tw!=0) { foundsec=1; }
509: if (i==8 && tw!=0) { foundpwd=1; }
510: }
511: verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
512: }
513:
514: function flip(vf,tf) {
515: var nw=eval('vf.f'+tf+'.selectedIndex');
516: var i;
517: // picked the all one one name field, reset the other name ones to blank
518: if (tf==1 && nw!=0) {
519: for (i=2;i<=5;i++) {
520: eval('vf.f'+i+'.selectedIndex=0;')
521: }
522: }
523: //picked one of the piecewise name fields, reset the all in
524: //one field to blank
525: if ((tf>=2) && (tf<=5) && (nw!=0)) {
526: eval('vf.f1.selectedIndex=0;')
527: }
528: // intial password specified, pick internal authentication
529: if (tf==8 && nw!=0) {
1.28 matthew 530: changed_radio('int',document.studentform);
531: set_auth_radio_buttons('int',document.studentform);
532: vf.krbarg.value='';
533: vf.intarg.value='';
1.24 albertel 534: vf.locarg.value='';
535: }
536: }
537:
538: function clearpwd(vf) {
539: var i;
540: if (eval('vf.f8.selectedIndex')!=0) {
541: eval('vf.f8.selectedIndex=0;')
542: }
543: }
1.2 www 544: ENDPICK
1.23 albertel 545: }
1.10 www 546:
1.50 matthew 547: ###############################################################
548: ###############################################################
549: sub print_upload_manager_footer {
1.23 albertel 550: my ($r,$i,$keyfields,$defdom,$today,$halfyear)=@_;
1.64 albertel 551:
552: my ($krbdef,$krbdefdom) =
553: &Apache::loncommon::get_kerberos_defaults($defdom);
554: my %param = ( formname => 'document.studentform',
555: kerb_def_dom => $krbdefdom,
556: kerb_def_auth => $krbdef
557: );
1.28 matthew 558: my $krbform = &Apache::loncommon::authform_kerberos(%param);
559: my $intform = &Apache::loncommon::authform_internal(%param);
560: my $locform = &Apache::loncommon::authform_local(%param);
1.31 matthew 561: my $domform = &domain_form($defdom);
1.68 matthew 562: my $date_table = &date_setting_table();
1.90 matthew 563: my $Str = "</table>\n";
564: $Str .= &hidden_input('nfields',$i);
565: $Str .= &hidden_input('keyfields',$keyfields);
566: $Str .= '<h3>'.&mt('Login Type')."</h3>\n";
567: $Str .= "<p>\n".
568: &mt('Note: this will not take effect if the user already exists').
569: "</p><p>\n";
570: $Str .= $krbform."\n</p><p>\n".
571: $intform."\n</p><p>\n".
572: $locform."\n</p>\n";
573: $Str .= '<h3>'.&mt('LON-CAPA Domain for Students')."</h3>\n";
574: $Str .= "<p>\n".&mt('LON-CAPA domain: [_1]',$domform)."\n</p>\n";
575: $Str .= "<h3>".&mt('Starting and Ending Dates')."</h3>\n";
576: $Str .= "<p>\n".$date_table."</p>\n";
577: $Str .= "<h3>".&mt('Full Update')."</h3>\n";
578: $Str .= '<input type="checkbox" name="fullup" value="yes">'.
579: ' '.&mt('Full update (also print list of users not enrolled anymore)').
580: "</p>\n";
581: $Str .= "<h3>".&mt('Student Number')."</h3>\n";
582: $Str .= "<p>\n".'<input type="checkbox" name="forceid" value="yes">';
583: $Str .= &mt('Disable ID/Student Number Safeguard and Force Change '.
584: 'of Conflicting IDs (only do if you know what you are doing)').
585: "\n</p><p>\n";
586: $Str .= '<input type="button" onClick="javascript:verify(this.form)" '.
1.95 albertel 587: 'value="Update Class List" />'."<br />\n";
1.90 matthew 588: $Str .= &mt('Note: for large courses, this operation may be time '.
589: 'consuming');
590: $r->print($Str);
591: return;
1.23 albertel 592: }
1.24 albertel 593:
1.90 matthew 594: ###############################################################
595: ###############################################################
1.50 matthew 596: sub print_upload_manager_form {
1.23 albertel 597: my $r=shift;
1.82 www 598: my $firstLine;
1.24 albertel 599: my $datatoken;
600: if (!$ENV{'form.datatoken'}) {
1.90 matthew 601: $datatoken=&Apache::loncommon::upfile_store($r);
1.24 albertel 602: } else {
1.90 matthew 603: $datatoken=$ENV{'form.datatoken'};
604: &Apache::loncommon::load_tmp_file($r);
1.24 albertel 605: }
606: my @records=&Apache::loncommon::upfile_record_sep();
1.90 matthew 607: if($ENV{'form.noFirstLine'}){
608: $firstLine=shift(@records);
609: }
1.23 albertel 610: my $total=$#records;
611: my $distotal=$total+1;
612: my $today=time;
613: my $halfyear=$today+15552000;
1.85 matthew 614: my $defdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
1.64 albertel 615: my ($krbdef,$krbdefdom) =
616: &Apache::loncommon::get_kerberos_defaults($defdom);
1.50 matthew 617: &print_upload_manager_header($r,$datatoken,$distotal,$krbdefdom);
1.24 albertel 618: my $i;
619: my $keyfields;
1.23 albertel 620: if ($total>=0) {
1.90 matthew 621: my @field=(['username',&mt('Username')],
622: ['names',&mt('Last Name, First Names')],
623: ['fname',&mt('First Name')],
624: ['mname',&mt('Middle Names/Initials')],
625: ['lname',&mt('Last Name')],
626: ['gen',&mt('Generation')],
627: ['id',&mt('ID/Student Number')],
628: ['sec',&mt('Group/Section')],
629: ['ipwd',&mt('Initial Password')],
630: ['email',&mt('EMail Address')]);
1.24 albertel 631: if ($ENV{'form.upfile_associate'} eq 'reverse') {
632: &Apache::loncommon::csv_print_samples($r,\@records);
1.90 matthew 633: $i=&Apache::loncommon::csv_print_select_table($r,\@records,
634: \@field);
635: foreach (@field) {
636: $keyfields.=$_->[0].',';
637: }
1.24 albertel 638: chop($keyfields);
639: } else {
1.90 matthew 640: unshift(@field,['none','']);
641: $i=&Apache::loncommon::csv_samples_select_table($r,\@records,
642: \@field);
1.24 albertel 643: my %sone=&Apache::loncommon::record_sep($records[0]);
644: $keyfields=join(',',sort(keys(%sone)));
1.23 albertel 645: }
646: }
1.50 matthew 647: &print_upload_manager_footer($r,$i,$keyfields,$defdom,$today,$halfyear);
1.10 www 648: }
649:
1.90 matthew 650: ###############################################################
651: ###############################################################
1.12 www 652: sub enroll_single_student {
653: my $r=shift;
1.80 matthew 654: # Remove non alphanumeric values from section
655: $ENV{'form.csec'}=~s/\W//g;
1.68 matthew 656: #
657: # We do the dates first because the action of making them the defaul
658: # in the course is entirely seperate from the action of enrolling the
659: # student. Also, a failure in setting the dates as default is not fatal
660: # to the process of enrolling / modifying a student.
661: my ($startdate,$enddate) = &get_dates_from_form();
662: if ($ENV{'form.makedatesdefault'}) {
663: $r->print(&make_dates_default($startdate,$enddate));
664: }
665:
1.94 sakharuk 666: $r->print('<h3>'.&mt('Enrolling Student').'</h3>');
667: $r->print('<p>'.&mt('Enrolling').' '.$ENV{'form.cuname'}." \@ ".
1.34 matthew 668: $ENV{'form.lcdomain'}.'</p>');
1.12 www 669: if (($ENV{'form.cuname'})&&($ENV{'form.cuname'}!~/\W/)&&
1.31 matthew 670: ($ENV{'form.lcdomain'})&&($ENV{'form.lcdomain'}!~/\W/)) {
671: # Deal with home server selection
672: my $domain=$ENV{'form.lcdomain'};
673: my $desiredhost = $ENV{'form.lcserver'};
674: if (lc($desiredhost) eq 'default') {
675: $desiredhost = undef;
676: } else {
1.45 matthew 677: my %home_servers =&Apache::loncommon::get_library_servers($domain);
1.31 matthew 678: if (! exists($home_servers{$desiredhost})) {
1.94 sakharuk 679: $r->print('<font color="#ff0000">'.&mt('Error').':</font>'.
680: &mt('Invalid home server specified'));
1.31 matthew 681: return;
682: }
683: }
1.94 sakharuk 684: $r->print(" ".&mt('with server')." $desiredhost :") if (defined($desiredhost));
1.31 matthew 685: # End of home server selection logic
1.12 www 686: my $amode='';
687: my $genpwd='';
688: if ($ENV{'form.login'} eq 'krb') {
1.47 albertel 689: $amode='krb';
690: $amode.=$ENV{'form.krbver'};
1.28 matthew 691: $genpwd=$ENV{'form.krbarg'};
1.12 www 692: } elsif ($ENV{'form.login'} eq 'int') {
1.26 matthew 693: $amode='internal';
1.28 matthew 694: $genpwd=$ENV{'form.intarg'};
1.15 albertel 695: } elsif ($ENV{'form.login'} eq 'loc') {
696: $amode='localauth';
697: $genpwd=$ENV{'form.locarg'};
698: if (!$genpwd) { $genpwd=" "; }
699: }
1.34 matthew 700: my $home = &Apache::lonnet::homeserver($ENV{'form.cuname'},
701: $ENV{'form.lcdomain'});
702: if ((($amode) && ($genpwd)) || ($home ne 'no_host')) {
1.55 matthew 703: # Clean out any old roles the student has in this class.
1.33 matthew 704: &modifystudent($ENV{'form.lcdomain'},$ENV{'form.cuname'},
705: $ENV{'request.course.id'},$ENV{'form.csec'},
706: $desiredhost);
1.55 matthew 707: my $login_result = &Apache::lonnet::modifystudent
708: ($ENV{'form.lcdomain'},$ENV{'form.cuname'},
709: $ENV{'form.cstid'},$amode,$genpwd,
710: $ENV{'form.cfirst'},$ENV{'form.cmiddle'},
711: $ENV{'form.clast'},$ENV{'form.cgen'},
1.67 matthew 712: $ENV{'form.csec'},$enddate,
713: $startdate,$ENV{'form.forceid'},
1.55 matthew 714: $desiredhost);
715: if ($login_result =~ /^ok/) {
716: $r->print($login_result);
1.94 sakharuk 717: $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 718: } else {
1.94 sakharuk 719: $r->print(&mt('unable to enroll').": ".$login_result);
1.55 matthew 720: }
1.12 www 721: } else {
1.94 sakharuk 722: $r->print('<p><font color="#ff0000">'.&mt('ERROR').'</font> ');
1.79 matthew 723: if ($amode =~ /^krb/) {
1.94 sakharuk 724: $r->print(&mt('Missing Kerberos domain information.').' ');
1.79 matthew 725: } else {
1.94 sakharuk 726: $r->print(&mt('Invalid login mode or password.').' ');
1.79 matthew 727: }
1.94 sakharuk 728: $r->print('<b>'.&mt('Unable to enroll').' '.$ENV{'form.cuname'}.'.</b></p>');
1.79 matthew 729: }
1.12 www 730: } else {
1.94 sakharuk 731: $r->print(&mt('Invalid username or domain'));
1.26 matthew 732: }
1.12 www 733: }
734:
1.68 matthew 735: sub setup_date_selectors {
1.91 raeburn 736: my ($starttime,$endtime,$mode) = @_;
1.68 matthew 737: if (! defined($starttime)) {
738: $starttime = time;
1.91 raeburn 739: unless ($mode eq 'createcourse') {
740: if (exists($ENV{'course.'.$ENV{'request.course.id'}.
1.68 matthew 741: '.default_enrollment_start_date'})) {
1.91 raeburn 742: $starttime = $ENV{'course.'.$ENV{'request.course.id'}.
1.68 matthew 743: '.default_enrollment_start_date'};
1.91 raeburn 744: }
1.68 matthew 745: }
746: }
747: if (! defined($endtime)) {
748: $endtime = time+(6*30*24*60*60); # 6 months from now, approx
1.91 raeburn 749: unless ($mode eq 'createcourse') {
750: if (exists($ENV{'course.'.$ENV{'request.course.id'}.
1.68 matthew 751: '.default_enrollment_end_date'})) {
1.91 raeburn 752: $endtime = $ENV{'course.'.$ENV{'request.course.id'}.
1.68 matthew 753: '.default_enrollment_end_date'};
1.91 raeburn 754: }
1.68 matthew 755: }
756: }
757: my $startdateform = &Apache::lonhtmlcommon::date_setter('studentform',
758: 'startdate',
759: $starttime);
760: my $enddateform = &Apache::lonhtmlcommon::date_setter('studentform',
761: 'enddate',
762: $endtime);
1.91 raeburn 763: if ($mode eq 'createcourse') {
764: $startdateform = &Apache::lonhtmlcommon::date_setter('ccrs',
765: 'startdate',
766: $starttime);
767: $enddateform = &Apache::lonhtmlcommon::date_setter('ccrs',
768: 'enddate',
769: $endtime);
770: }
1.68 matthew 771: return ($startdateform,$enddateform);
772: }
773:
774: sub get_dates_from_form {
775: my $startdate = &Apache::lonhtmlcommon::get_date_from_form('startdate');
776: my $enddate = &Apache::lonhtmlcommon::get_date_from_form('enddate');
777: if ($ENV{'form.no_end_date'}) {
778: $enddate = 0;
779: }
780: return ($startdate,$enddate);
781: }
782:
783: sub date_setting_table {
1.91 raeburn 784: my ($starttime,$endtime,$mode) = @_;
785: my ($startform,$endform)=&setup_date_selectors($starttime,$endtime,$mode);
1.68 matthew 786: my $dateDefault = '<nobr>'.
1.94 sakharuk 787: '<input type="checkbox" name="makedatesdefault" /> '.
788: &mt('make these dates the default for future enrollment');
1.91 raeburn 789: if ($mode eq 'createcourse') {
790: $dateDefault = ' ';
791: }
1.68 matthew 792: my $perpetual = '<nobr><input type="checkbox" name="no_end_date"';
793: if (defined($endtime) && $endtime == 0) {
794: $perpetual .= ' checked';
795: }
1.94 sakharuk 796: $perpetual.= ' /> '.&mt('no ending date').'</nobr>';
1.68 matthew 797: my $result = '';
798: $result .= "<table>\n";
1.94 sakharuk 799: $result .= '<tr><td align="right">'.&mt('Starting Date').'</td>'.
1.68 matthew 800: '<td>'.$startform.'</td>'.
801: '<td>'.$dateDefault.'</td>'."</tr>\n";
1.94 sakharuk 802: $result .= '<tr><td align="right">'.&mt('Ending Date').'</td>'.
1.68 matthew 803: '<td>'.$endform.'</td>'.
804: '<td>'.$perpetual.'</td>'."</tr>\n";
805: $result .= "</table>\n";
806: return $result;
807: }
808:
809: sub make_dates_default {
810: my ($startdate,$enddate) = @_;
811: my $result = '';
812: my $dom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
813: my $crs = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
814: my $put_result = &Apache::lonnet::put('environment',
815: {'default_enrollment_start_date'=>$startdate,
816: 'default_enrollment_end_date' =>$enddate},$dom,$crs);
817: if ($put_result eq 'ok') {
818: $result .= "Set default start and end dates for course<br />";
1.69 matthew 819: #
820: # Refresh the course environment
821: &Apache::lonnet::coursedescription($ENV{'request.course.id'});
1.68 matthew 822: } else {
1.94 sakharuk 823: $result .= &mt('Unable to set default dates for course').":".$put_result.
1.68 matthew 824: '<br />';
825: }
826: return $result;
827: }
828:
1.74 matthew 829: ##
830: ## Single student enrollment routines (some of them)
831: ##
832: sub get_student_username_domain_form {
833: my $r = shift;
834: my $domform = &Apache::loncommon::select_dom_form
1.85 matthew 835: ($ENV{'course.'.$ENV{'request.course.id'}.'.domain'},'cudomain',0);
1.94 sakharuk 836: my %lt=&Apache::lonlocal::texthash(
837: 'eos' => "Enroll One Student",
838: 'usr' => "Username",
839: 'dom' => "Domain",
840: 'been' => "Begin Enrollment",
841: );
1.74 matthew 842: $r->print(<<END);
843: <input type="hidden" name="action" value="enrollstudent" />
844: <input type="hidden" name="state" value="gotusername" />
1.94 sakharuk 845: <h3>$lt{'eos'}</h3>
1.74 matthew 846: <table>
1.94 sakharuk 847: <tr><th>$lt{'usr'}:</th>
1.74 matthew 848: <td><input type="text" name="cuname" size="15" /></td></tr>
1.94 sakharuk 849: <tr><th>$lt{'dom'}:</th>
1.74 matthew 850: <td>$domform</td></tr>
851: <tr><th> </th>
852: <td>
1.94 sakharuk 853: <input type="submit" name="Begin Enrollment" value="$lt{'been'}" />
1.74 matthew 854: </td></tr>
855: </table>
856: END
857: return;
858: }
859:
1.50 matthew 860: sub print_enroll_single_student_form {
1.10 www 861: my $r=shift;
1.94 sakharuk 862: $r->print("<h3>".&mt('Enroll One Student')."</h3>");
1.74 matthew 863: #
864: my $username = $ENV{'form.cuname'};
865: my $domain = $ENV{'form.cudomain'};
866: my $home = &Apache::lonnet::homeserver($username,$domain);
867: # $new_user flags whether we are creating a new user or using an old one
868: my $new_user = 1;
869: if ($home ne 'no_host') {
870: $new_user = 0;
871: }
872: #
873: my $user_data_html = '';
874: my $javascript_validations = '';
875: if ($new_user) {
1.85 matthew 876: my $defdom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
1.74 matthew 877: # Set up authentication forms
878: my ($krbdef,$krbdefdom) =
1.75 matthew 879: &Apache::loncommon::get_kerberos_defaults($domain);
1.89 matthew 880: $javascript_validations=&javascript_validations('auth',$krbdefdom);
1.74 matthew 881: my %param = ( formname => 'document.studentform',
882: kerb_def_dom => $krbdefdom,
883: kerb_def_auth => $krbdef
884: );
885: my $krbform = &Apache::loncommon::authform_kerberos(%param);
886: my $intform = &Apache::loncommon::authform_internal(%param);
887: my $locform = &Apache::loncommon::authform_local(%param);
888: #
889: # Set up domain selection form
890: my $homeserver_form = '';
891: my %servers = &Apache::loncommon::get_library_servers($domain);
892: $homeserver_form = '<select name="lcserver" size="1">'."\n".
893: '<option value="default" selected>default</option>'."\n";
894: while (my ($servername,$serverdescription) = each (%servers)) {
895: $homeserver_form .= '<option value="'.$servername.'">'.
896: $serverdescription."</option>\n";
897: }
898: $homeserver_form .= "</select>\n";
899: #
900: #
1.94 sakharuk 901: my %lt=&Apache::lonlocal::texthash(
902: 'udf' => "User Data for",
903: 'fn' => "First Name",
904: 'mn' => "Middle Name",
905: 'ln' => "Last Name",
906: 'gen' => "Generation",
907: 'hs' => "Home Server",
908: 'pswd' => "Password",
909: 'psam' => "Please select an authentication mechanism",
910: );
1.74 matthew 911: $user_data_html = <<END;
1.94 sakharuk 912: <h3>$lt{'udf'} $username\@$domain</h3>
1.74 matthew 913: <table>
1.94 sakharuk 914: <tr><th>$lt{'fn'}:</th>
1.74 matthew 915: <td><input type="text" name="cfirst" size="15"></td></tr>
1.94 sakharuk 916: <tr><th>$lt{'mn'}:</th>
1.74 matthew 917: <td><input type="text" name="cmiddle" size="15"></td></tr>
1.94 sakharuk 918: <tr><th>$lt{'ln'}:</th>
1.74 matthew 919: <td><input type="text" name="clast" size="15"></td></tr>
1.94 sakharuk 920: <tr><th>$lt{'gen'}:</th>
1.74 matthew 921: <td><input type="text" name="cgen" size="5"> </td></tr>
1.94 sakharuk 922: <tr><th>$lt{'hs'}:</th>
1.74 matthew 923: <td>$homeserver_form</td></tr>
924: </table>
1.94 sakharuk 925: <h3>$lt{'pswd'}</h3>
926: $lt{'psam'}
1.74 matthew 927: <table>
928: <p>
929: $krbform
1.75 matthew 930: <br />
1.74 matthew 931: $intform
1.75 matthew 932: <br />
1.74 matthew 933: $locform
934: </p>
935: END
936: } else {
937: # User already exists. Do not worry about authentication
938: my %uenv = &Apache::lonnet::dump('environment',$domain,$username);
1.89 matthew 939: $javascript_validations = &javascript_validations('noauth');
1.94 sakharuk 940: my %lt=&Apache::lonlocal::texthash(
941: 'udf' => "User Data for",
942: 'fn' => "First Name",
943: 'mn' => "Middle Name",
944: 'ln' => "Last Name",
945: 'gen' => "Generation",
946: );
1.74 matthew 947: $user_data_html = <<END;
1.94 sakharuk 948: <h3>$lt{'udf'} $username\@$domain</h3>
1.74 matthew 949: <input type="hidden" name="lcserver" value="default" />
950: <table>
1.94 sakharuk 951: <tr><th>$lt{'fn'}:</th>
1.74 matthew 952: <td>
953: <input type="text" name="cfirst" value="$uenv{'firstname'}" size="15" />
954: </td></tr>
1.94 sakharuk 955: <tr><th>$lt{'mn'}:</th>
1.74 matthew 956: <td>
957: <input type="text" name="cmiddle" value="$uenv{'middlename'}" size="15" />
958: </td></tr>
1.94 sakharuk 959: <tr><th>$lt{'ln'}:</th>
1.74 matthew 960: <td>
961: <input type="text" name="clast"value="$uenv{'lastname'}" size="15" />
962: </td></tr>
1.94 sakharuk 963: <tr><th>$lt{'gen'}:</th>
1.74 matthew 964: <td>
965: <input type="text" name="cgen" value="$uenv{'generation'}" size="5" />
966: </td></tr>
967: </table>
968: END
969: }
1.68 matthew 970: my $date_table = &date_setting_table();
1.74 matthew 971: # Print it all out
1.94 sakharuk 972: my %lt=&Apache::lonlocal::texthash(
973: 'cd' => "Course Data",
974: 'gs' => "Group/Section",
975: 'idsn' => "ID/Student Number",
976: 'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
977: 'eas' => "Enroll as student",
978: );
1.50 matthew 979: $r->print(<<END);
1.74 matthew 980: <input type="hidden" name="action" value="enrollstudent" />
981: <input type="hidden" name="state" value="done" />
982: <input type="hidden" name="cuname" value="$username" />
983: <input type="hidden" name="lcdomain" value="$domain" />
1.28 matthew 984: <script type="text/javascript" language="Javascript">
1.12 www 985: function verify(vf) {
986: var founduname=0;
987: var foundpwd=0;
988: var foundname=0;
989: var foundid=0;
990: var foundsec=0;
991: var tw;
1.26 matthew 992: if ((typeof(vf.cuname.value) !="undefined") && (vf.cuname.value!='') &&
1.31 matthew 993: (typeof(vf.lcdomain.value)!="undefined") && (vf.lcdomain.value!='')) {
1.12 www 994: founduname=1;
995: }
1.14 harris41 996: if ((typeof(vf.cfirst.value)!="undefined") && (vf.cfirst.value!='') &&
1.26 matthew 997: (typeof(vf.clast.value) !="undefined") && (vf.clast.value!='')) {
1.12 www 998: foundname=1;
999: }
1.14 harris41 1000: if ((typeof(vf.csec.value)!="undefined") && (vf.csec.value!='')) {
1.12 www 1001: foundsec=1;
1002: }
1.14 harris41 1003: if ((typeof(vf.cstid.value)!="undefined") && (vf.cstid.value!='')) {
1.12 www 1004: foundid=1;
1005: }
1006: if (founduname==0) {
1007: alert('You need to specify at least the username and domain fields');
1008: return;
1009: }
1.24 albertel 1010: verify_message(vf,founduname,foundpwd,foundname,foundid,foundsec);
1.12 www 1011: }
1012:
1.24 albertel 1013: $javascript_validations
1.12 www 1014:
1.24 albertel 1015: function clearpwd(vf) {
1016: //nothing else needs clearing
1.15 albertel 1017: }
1018:
1.12 www 1019: </script>
1.11 www 1020:
1.74 matthew 1021: $user_data_html
1.50 matthew 1022:
1.94 sakharuk 1023: <h3>$lt{'cd'}</h3>
1.50 matthew 1024:
1.94 sakharuk 1025: <p>$lt{'gs'}: <input type="text" name="csec" size="5" />
1.50 matthew 1026: <p>
1.68 matthew 1027: $date_table
1.50 matthew 1028: </p>
1.94 sakharuk 1029: <h3>$lt{'idsn'}</h3>
1.50 matthew 1030: <p>
1.94 sakharuk 1031: $lt{'idsn'}: <input type="text" name="cstid" size="10">
1.26 matthew 1032: </p><p>
1033: <input type="checkbox" name="forceid" value="yes">
1.94 sakharuk 1034: $lt{'disn'}
1.50 matthew 1035: </p><p>
1.94 sakharuk 1036: <input type="button" onClick="verify(this.form)" value="$lt{'eas'}">
1.26 matthew 1037: </p>
1.50 matthew 1038: END
1039: return;
1.10 www 1040: }
1041:
1042: # ========================================================= Menu Phase Two Drop
1.51 matthew 1043: sub print_drop_menu {
1.10 www 1044: my $r=shift;
1.92 sakharuk 1045: $r->print("<h3>".&mt('Drop Students')."</h3>");
1.11 www 1046: my $cid=$ENV{'request.course.id'};
1.56 matthew 1047: my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
1048: if (! defined($classlist)) {
1.94 sakharuk 1049: $r->print(&mt('There are no students currently enrolled.')."\n");
1.51 matthew 1050: return;
1.25 matthew 1051: }
1.51 matthew 1052: # Print out the available choices
1.56 matthew 1053: &show_drop_list($r,$classlist,$keylist);
1.51 matthew 1054: return;
1.11 www 1055: }
1056:
1.40 matthew 1057: # ============================================== view classlist
1.50 matthew 1058: sub print_html_classlist {
1.40 matthew 1059: my $r=shift;
1.57 matthew 1060: if (! exists($ENV{'form.sortby'})) {
1061: $ENV{'form.sortby'} = 'username';
1062: }
1.59 matthew 1063: if ($ENV{'form.Status'} !~ /^(Any|Expired|Active)$/) {
1.57 matthew 1064: $ENV{'form.Status'} = 'Active';
1065: }
1066: my $status_select = &Apache::lonhtmlcommon::StatusOptions
1067: ($ENV{'form.Status'},'studentform');
1.94 sakharuk 1068: my $CCL=&mt('Current Class List');
1.48 matthew 1069: $r->print(<<END);
1.58 matthew 1070: <input type="hidden" name="action" value="$ENV{'form.action'}" />
1.57 matthew 1071: <input type="hidden" name="state" value="" />
1.50 matthew 1072: <p>
1.94 sakharuk 1073: <font size="+1">$CCL</font>
1.57 matthew 1074:
1.59 matthew 1075: END
1076: if ($ENV{'form.action'} ne 'modifystudent') {
1.94 sakharuk 1077: my %lt=&Apache::lonlocal::texthash(
1078: 'ef' => "Excel format",
1079: 'ss' => "Student Status",
1080: );
1.59 matthew 1081: $r->print(<<END);
1.57 matthew 1082: <font size="+1">
1083: <a href="javascript:document.studentform.state.value='csv';document.studentform.submit();">CSV format</a>
1.61 matthew 1084:
1.94 sakharuk 1085: <a href="javascript:document.studentform.state.value='excel';document.studentform.submit();">$lt{'ef'}</a>
1.57 matthew 1086: </font>
1087:
1.94 sakharuk 1088: $lt{'ss'}:
1.48 matthew 1089: END
1.59 matthew 1090: }
1091: $r->print($status_select."</p>\n");
1.40 matthew 1092: my $cid=$ENV{'request.course.id'};
1.56 matthew 1093: my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
1094: if (! defined($classlist)) {
1.94 sakharuk 1095: $r->print(&mt('There are no students currently enrolled.')."\n");
1.40 matthew 1096: } else {
1097: # Print out the available choices
1.50 matthew 1098: if ($ENV{'form.action'} eq 'modifystudent') {
1.53 matthew 1099: &show_class_list($r,'view','modify','modifystudent',
1.57 matthew 1100: $ENV{'form.Status'},$classlist,$keylist);
1.50 matthew 1101: } else {
1.53 matthew 1102: &show_class_list($r,'view','aboutme','classlist',
1.57 matthew 1103: $ENV{'form.Status'},$classlist,$keylist);
1.50 matthew 1104: }
1.41 matthew 1105: }
1106: }
1107:
1108: # ============================================== view classlist
1.60 matthew 1109: sub print_formatted_classlist {
1.41 matthew 1110: my $r=shift;
1.60 matthew 1111: my $mode = shift;
1.41 matthew 1112: my $cid=$ENV{'request.course.id'};
1.56 matthew 1113: my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
1114: if (! defined($classlist)) {
1.94 sakharuk 1115: $r->print(&mt('There are no students currently enrolled.')."\n");
1.41 matthew 1116: } else {
1.60 matthew 1117: &show_class_list($r,$mode,'nolink','csv',
1.57 matthew 1118: $ENV{'form.Status'},$classlist,$keylist);
1.40 matthew 1119: }
1120: }
1121:
1122: # =================================================== Show student list to drop
1123: sub show_class_list {
1.56 matthew 1124: my ($r,$mode,$linkto,$action,$statusmode,$classlist,$keylist)=@_;
1.40 matthew 1125: my $cid=$ENV{'request.course.id'};
1.60 matthew 1126: #
1127: # Variables for excel output
1128: my ($excel_workbook, $excel_sheet, $excel_filename,$row);
1129: #
1.53 matthew 1130: my $sortby = $ENV{'form.sortby'};
1131: if ($sortby !~ /^(username|domain|section|fullname|id)$/) {
1132: $sortby = 'username';
1133: }
1.42 matthew 1134: # Print out header
1.41 matthew 1135: if ($mode eq 'view') {
1.50 matthew 1136: if ($linkto eq 'aboutme') {
1.94 sakharuk 1137: $r->print(&mt('Select a user name to view the users personal page.'));
1.50 matthew 1138: } elsif ($linkto eq 'modify') {
1.94 sakharuk 1139: $r->print(&mt('Select a user name to modify the students information'));
1.50 matthew 1140: }
1.94 sakharuk 1141: my %lt=&Apache::lonlocal::texthash(
1142: 'usrn' => "username",
1143: 'dom' => "domain",
1144: 'sn' => "student name",
1145: 'sec' => "section",
1146: );
1.41 matthew 1147: $r->print(<<END);
1.59 matthew 1148:
1.53 matthew 1149: <input type="hidden" name="sortby" value="$sortby" />
1.59 matthew 1150: <input type="hidden" name="sname" value="" />
1151: <input type="hidden" name="sdom" value="" />
1.40 matthew 1152: <p>
1153: <table border=2>
1.53 matthew 1154: <tr><th>
1.94 sakharuk 1155: <a href="javascript:document.studentform.sortby.value='username';document.studentform.submit();">$lt{'usrn'}</a>
1.53 matthew 1156: </th><th>
1.94 sakharuk 1157: <a href="javascript:document.studentform.sortby.value='domain';document.studentform.submit();">$lt{'dom'}</a>
1.53 matthew 1158: </th><th>
1.57 matthew 1159: <a href="javascript:document.studentform.sortby.value='id';document.studentform.submit();">ID</a>
1.53 matthew 1160: </th><th>
1.94 sakharuk 1161: <a href="javascript:document.studentform.sortby.value='fullname';document.studentform.submit();">$lt{'sn'}</a>
1.53 matthew 1162: </th><th>
1.94 sakharuk 1163: <a href="javascript:document.studentform.sortby.value='section';document.studentform.submit();">$lt{'sec'}</a>
1.53 matthew 1164: </th>
1165: </tr>
1.40 matthew 1166: END
1.41 matthew 1167: } elsif ($mode eq 'csv') {
1.58 matthew 1168: if($statusmode eq 'Expired') {
1.94 sakharuk 1169: $r->print(&mt('Students with expired roles'));
1.58 matthew 1170: }
1171: if ($statusmode eq 'Any') {
1.94 sakharuk 1172: $r->print('"'.join('","',(&mt("username"),&mt("domain"),"ID",
1173: &mt("student name"),&mt("section"),&mt("status"))).
1174: '"'."\n");
1.58 matthew 1175: } else {
1.94 sakharuk 1176: $r->print('"'.join('","',(&mt("username"),&mt("domain"),"ID",
1177: &mt("student name"),&mt("section"))).'"'."\n");
1.58 matthew 1178: }
1.60 matthew 1179: } elsif ($mode eq 'excel') {
1180: # Create the excel spreadsheet
1181: $excel_filename = '/prtspool/'.
1182: $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
1183: time.'_'.rand(1000000000).'.xls';
1184: $excel_workbook = Spreadsheet::WriteExcel->new('/home/httpd'.
1185: $excel_filename);
1186: $excel_workbook->set_tempdir('/home/httpd/perl/tmp');
1187: $excel_sheet = $excel_workbook->addworksheet('classlist');
1188: #
1.76 albertel 1189: my $description = 'Class List for '.
1.60 matthew 1190: $ENV{'course.'.$ENV{'request.course.id'}.'.description'};
1191: $excel_sheet->write($row++,0,$description);
1192: #
1193: $excel_sheet->write($row++,0,["username","domain","ID",
1194: "student name","section","status"]);
1.41 matthew 1195: }
1.56 matthew 1196: #
1197: # Sort the students
1198: my %index;
1199: my $i;
1200: foreach (@$keylist) {
1201: $index{$_} = $i++;
1202: }
1203: my $index = $index{$sortby};
1204: my $second = $index{'username'};
1205: my $third = $index{'domain'};
1.53 matthew 1206: my @Sorted_Students = sort {
1.56 matthew 1207: lc($classlist->{$a}->[$index]) cmp lc($classlist->{$b}->[$index])
1208: ||
1209: lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
1210: ||
1211: lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
1212: } (keys(%$classlist));
1.53 matthew 1213: foreach my $student (@Sorted_Students) {
1.56 matthew 1214: my $username = $classlist->{$student}->[$index{'username'}];
1215: my $domain = $classlist->{$student}->[$index{'domain'}];
1216: my $section = $classlist->{$student}->[$index{'section'}];
1217: my $name = $classlist->{$student}->[$index{'fullname'}];
1218: my $id = $classlist->{$student}->[$index{'id'}];
1219: my $status = $classlist->{$student}->[$index{'status'}];
1.57 matthew 1220: next if (($statusmode ne 'Any') && ($status ne $statusmode));
1.51 matthew 1221: if ($mode eq 'view') {
1222: $r->print("<tr>\n <td>\n ");
1223: if ($linkto eq 'nothing') {
1224: $r->print($username);
1225: } elsif ($linkto eq 'aboutme') {
1226: $r->print(&Apache::loncommon::aboutmewrapper($username,
1227: $username,
1228: $domain));
1229: } elsif ($linkto eq 'modify') {
1.59 matthew 1230: $r->print('<a href="'.
1231: "javascript:document.studentform.sname.value='".
1232: $username.
1233: "';document.studentform.sdom.value='".$domain.
1234: "';document.studentform.state.value='selected".
1235: "';document.studentform.submit();".'">'.
1.53 matthew 1236: $username."</a>\n");
1.50 matthew 1237: }
1.51 matthew 1238: $r->print(<<"END");
1.50 matthew 1239: </td>
1.51 matthew 1240: <td>$domain</td>
1241: <td>$id</td>
1242: <td>$name</td>
1243: <td>$section</td>
1.40 matthew 1244: </tr>
1245: END
1.51 matthew 1246: } elsif ($mode eq 'csv') {
1247: # no need to bother with $linkto
1248: my @line = ();
1249: foreach ($username,$domain,$id,$name,$section) {
1250: push @line,&Apache::loncommon::csv_translate($_);
1.58 matthew 1251: }
1252: if ($statusmode eq 'Any') {
1253: push @line,&Apache::loncommon::csv_translate($status);
1.41 matthew 1254: }
1.51 matthew 1255: my $tmp = $";
1256: $" = '","';
1257: $r->print("\"@line\"\n");
1258: $" = $tmp;
1.60 matthew 1259: } elsif ($mode eq 'excel') {
1260: $excel_sheet->write($row++,0,[$username,$domain,$id,
1261: $name,$section,$status]);
1.40 matthew 1262: }
1263: }
1.60 matthew 1264: if ($mode eq 'view') {
1265: $r->print('</table><br>');
1266: } elsif ($mode eq 'excel') {
1267: $excel_workbook->close();
1268: $r->print('<p><a href="'.$excel_filename.'">'.
1.94 sakharuk 1269: &mt('Your Excel spreadsheet').'</a> '.&mt('is ready for download').'.</p>'."\n");
1.60 matthew 1270: }
1.40 matthew 1271: }
1272:
1.50 matthew 1273:
1274: #
1275: # print out form for modification of a single students data
1276: #
1277: sub print_modify_student_form {
1278: my $r = shift();
1279: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.59 matthew 1280: ['sdom','sname']);
1.53 matthew 1281: my $sname = $ENV{'form.sname'};
1282: my $sdom = $ENV{'form.sdom'};
1283: my $sortby = $ENV{'form.sortby'};
1.50 matthew 1284: # determine the students name information
1285: my %info=&Apache::lonnet::get('environment',
1286: ['firstname','middlename',
1.52 matthew 1287: 'lastname','generation','id'],
1.50 matthew 1288: $sdom, $sname);
1289: my ($tmp) = keys(%info);
1290: if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94 sakharuk 1291: $r->print('<font color="#ff0000" size="+2">'.&mt('Error').'</font>'.
1.50 matthew 1292: '<p>'.
1.94 sakharuk 1293: &mt('Unable to retrieve environment data for').' '.$sname.
1294: &mt('in domain').' '.$sdom.'</p><p>'.
1295: &mt('Please contact your LON-CAPA administrator regarding this situation.').'</p></body></html>');
1.50 matthew 1296: return;
1297: }
1298: # determine the students starting and ending times and section
1299: my ($starttime,$endtime,$section) = &get_enrollment_data($sname,$sdom);
1.87 matthew 1300: if ($starttime =~ /^error/) {
1.94 sakharuk 1301: $r->print('<h2>'&mt('Error').'</h2>');
1.87 matthew 1302: $r->print('<p>'.$starttime.'</p>');
1303: return;
1304: }
1.50 matthew 1305: # Deal with date forms
1.68 matthew 1306: my $date_table = &date_setting_table($starttime,$endtime);
1.59 matthew 1307: #
1308: if (! exists($ENV{'form.Status'}) ||
1309: $ENV{'form.Status'} !~ /^(Any|Expired|Active)$/) {
1310: $ENV{'form.Status'} = 'crap';
1311: }
1.94 sakharuk 1312: # Make sure student is enrolled in course
1313: my %lt=&Apache::lonlocal::texthash(
1314: 'mef' => "Modify Enrollment for",
1315: 'odcc' => "Only domain coordinators can change a users password.",
1316: 'sn' => "Student Name",
1317: 'fn' => "First",
1318: 'mn' => "Middle",
1319: 'ln' => "Last",
1320: 'gen' => "Generation",
1321: 'sid' => "Student ID",
1322: 'disn' => "Disable ID/Student Number Safeguard and Force Change of Conflicting IDs (only do if you know what you are doing)",
1323: 'sec' => "Section",
1324: 'sm' => "Submit Modifications",
1325: );
1.50 matthew 1326: $r->print(<<END);
1.52 matthew 1327: <p>
1328: <font size="+1">
1.94 sakharuk 1329: $lt{'odcc'}
1.52 matthew 1330: </font>
1331: </p>
1.50 matthew 1332: <input type="hidden" name="slogin" value="$sname" />
1333: <input type="hidden" name="sdomain" value="$sdom" />
1334: <input type="hidden" name="action" value="modifystudent" />
1.53 matthew 1335: <input type="hidden" name="state" value="done" />
1336: <input type="hidden" name="sortby" value="$sortby" />
1.59 matthew 1337: <input type="hidden" name="Status" value="$ENV{'form.Status'}" />
1338:
1.94 sakharuk 1339: <h2>$lt{'mef'} $info{'firstname'} $info{'middlename'}
1.50 matthew 1340: $info{'lastname'} $info{'generation'}, $sname\@$sdom</h2>
1341: <p>
1.94 sakharuk 1342: <b>$lt{'sn'}</b>
1.50 matthew 1343: <table>
1.94 sakharuk 1344: <tr><th>$lt{'fn'}</th><th>$lt{'mn'}</th><th>$lt{'ln'}</th><th>$lt{'gen'}</th></tr>
1.50 matthew 1345: <tr><td>
1346: <input type="text" name="firstname" value="$info{'firstname'}" /></td><td>
1347: <input type="text" name="middlename" value="$info{'middlename'}" /></td><td>
1348: <input type="text" name="lastname" value="$info{'lastname'}" /></td><td>
1349: <input type="text" name="generation" value="$info{'generation'}" /></td></tr>
1350: </table>
1351: </p><p>
1.94 sakharuk 1352: <b>$lt{'sid'}</b>: <input type="text" name="id" value="$info{'id'}" size="12"/>
1.52 matthew 1353: </p><p>
1.53 matthew 1354: <input type="checkbox" name="forceid" >
1.94 sakharuk 1355: $lt{'disn'}
1.53 matthew 1356: </p><p>
1.94 sakharuk 1357: <b>$lt{'sec'}</b>: <input type="text" name="section" value="$section" size="4"/>
1.50 matthew 1358: </p>
1.68 matthew 1359: <p>$date_table</p>
1.94 sakharuk 1360: <input type="submit" value="$lt{'sm'}" />
1.50 matthew 1361: </body></html>
1362: END
1363: return;
1364: }
1365:
1366: #
1367: # modify a single students section
1368: #
1369: sub modify_single_student {
1370: my $r = shift;
1.68 matthew 1371: #
1.80 matthew 1372: # Remove non alphanumeric values from the section
1373: $ENV{'form.section'} =~ s/\W//g;
1.77 matthew 1374: #
1.68 matthew 1375: # Do the date defaults first
1376: my ($starttime,$endtime) = &get_dates_from_form();
1377: if ($ENV{'form.makedatesdefault'}) {
1378: $r->print(&make_dates_default($starttime,$endtime));
1379: }
1.59 matthew 1380: # Get the 'sortby' and 'Status' variables so the user goes back to their
1381: # previous screen
1.53 matthew 1382: my $sortby = $ENV{'form.sortby'};
1.59 matthew 1383: my $status = $ENV{'form.Status'};
1.53 matthew 1384: #
1385: # We always need this information
1386: my $slogin = $ENV{'form.slogin'};
1387: my $sdom = $ENV{'form.sdomain'};
1388: #
1389: # Get the old data
1390: my %old=&Apache::lonnet::get('environment',
1391: ['firstname','middlename',
1392: 'lastname','generation','id'],
1393: $sdom, $slogin);
1.59 matthew 1394: $old{'section'} = &Apache::lonnet::getsection($sdom,$slogin,
1395: $ENV{'request.course.id'});
1.53 matthew 1396: my ($tmp) = keys(%old);
1397: if ($tmp =~ /^(con_lost|error|no_such_host)/i) {
1.94 sakharuk 1398: $r->print(&mt('There was an error determining the environment values for')." $slogin \@ $sdom.");
1.53 matthew 1399: return;
1400: }
1401: undef $tmp;
1402: #
1403: # Get the new data
1.50 matthew 1404: my $firstname = $ENV{'form.firstname'};
1405: my $middlename = $ENV{'form.middlename'};
1406: my $lastname = $ENV{'form.lastname'};
1407: my $generation = $ENV{'form.generation'};
1408: my $section = $ENV{'form.section'};
1409: my $courseid = $ENV{'request.course.id'};
1.52 matthew 1410: my $sid = $ENV{'form.id'};
1.50 matthew 1411: my $displayable_starttime = localtime($starttime);
1412: my $displayable_endtime = localtime($endtime);
1.53 matthew 1413: #
1414: # check for forceid override
1.63 matthew 1415: if ((defined($old{'id'})) && ($old{'id'} ne '') &&
1416: ($sid ne $old{'id'}) && (! exists($ENV{'form.forceid'}))) {
1.94 sakharuk 1417: $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 1418: $sid = $old{'id'};
1419: }
1420: #
1.50 matthew 1421: # talk to the user about what we are going to do
1.94 sakharuk 1422: my %lt=&Apache::lonlocal::texthash(
1423: 'mdu' => "Modifying data for user",
1424: 'si' => "Student Information",
1425: 'fd' => "Field",
1426: 'ov' => "Old Value",
1427: 'nv' => "New Value",
1428: 'fn' => "First name",
1429: 'mn' => "Middle name",
1430: 'ln' => "Last name",
1431: 'gen' => "Generation",
1432: 'sec' => "Section",
1433: 'ri' => "Role Information",
1434: 'st' => "Start Time",
1435: 'et' => "End Time",
1436: );
1.50 matthew 1437: $r->print(<<END);
1.94 sakharuk 1438: <h2>$lt{'mdu'} $slogin \@ $sdom </h2>
1439: <h3>$lt{'si'}</h3>
1.53 matthew 1440: <table rules="rows" border="1" cellpadding="3" >
1441: <tr>
1.94 sakharuk 1442: <th> $lt{'fd'} </th>
1443: <th> $lt{'ov'} </th>
1444: <th> $lt{'nv'} </th>
1.53 matthew 1445: </tr>
1446: <tr>
1.94 sakharuk 1447: <td> <b>$lt{'fn'}</b> </td>
1.53 matthew 1448: <td> $old{'firstname'} </td>
1449: <td> $firstname </td>
1450: </tr><tr>
1.94 sakharuk 1451: <td> <b>$lt{'mn'}</b> </td>
1.53 matthew 1452: <td> $old{'middlename'} </td>
1453: <td> $middlename </td>
1454: </tr><tr>
1.94 sakharuk 1455: <td> <b>$lt{'ln'}</b> </td>
1.53 matthew 1456: <td> $old{'lastname'} </td>
1457: <td> $lastname </td>
1458: </tr><tr>
1.94 sakharuk 1459: <td> <b>$lt{'gen'}</b> </td>
1.53 matthew 1460: <td> $old{'generation'} </td>
1461: <td> $generation </td>
1462: </tr><tr>
1463: <td> <b>ID</b> </td>
1464: <td> $old{'id'} </td>
1465: <td> $sid </td>
1.59 matthew 1466: </tr><tr>
1.94 sakharuk 1467: <td> <b>$lt{'sec'}</b> </td>
1.59 matthew 1468: <td> $old{'section'} </td>
1469: <td> $section</td>
1.53 matthew 1470: </tr>
1.50 matthew 1471: </table>
1.94 sakharuk 1472: <h3>$lt{'ri'}</h3>
1.50 matthew 1473: <table>
1.94 sakharuk 1474: <tr><td align="right"><b>$lt{'st'}:</b></td><td> $displayable_starttime </td></tr>
1475: <tr><td align="right"><b>$lt{'et'}:</b></td><td> $displayable_endtime </td></tr>
1.50 matthew 1476: </table>
1.52 matthew 1477: <p>
1.50 matthew 1478: END
1.53 matthew 1479: #
1.63 matthew 1480: # Send request(s) to modify data (final undef is for 'desiredhost',
1481: # which is a moot point because the student already has an account.
1482: my $modify_section_results = &modifystudent($sdom,$slogin,
1483: $ENV{'request.course.id'},
1484: $section,undef);
1485: if ($modify_section_results !~ /^ok/) {
1.94 sakharuk 1486: $r->print(&mt('An error occured during the attempt to change the section for this student.')."<br />");
1.63 matthew 1487: }
1.52 matthew 1488: my $roleresults = &Apache::lonnet::modifystudent
1.53 matthew 1489: ($sdom,$slogin,$sid,undef,undef,$firstname,$middlename,$lastname,
1490: $generation,$section,$endtime,$starttime,$ENV{'form.forceid'});
1491: if ($roleresults eq 'refused' ) {
1.94 sakharuk 1492: $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 1493: } elsif ($roleresults !~ /ok/) {
1.94 sakharuk 1494: $r->print(&mt('An error occurred during the attempt to change the role information for this student.')." <br />".
1495: &mt('The error reported was')." ".
1.50 matthew 1496: $roleresults);
1.53 matthew 1497: &Apache::lonnet::logthis("londropadd:failed attempt to modify student".
1498: " data for ".$slogin." \@ ".$sdom." by ".
1499: $ENV{'user.name'}." \@ ".$ENV{'user.domain'}.
1500: ":".$roleresults);
1.50 matthew 1501: } else { # everything is okay!
1.94 sakharuk 1502: $r->print(&mt('Student information updated successfully.')." <br />".
1503: &mt('The student must log out and log in again to see these changes.'));
1.50 matthew 1504: }
1.94 sakharuk 1505: my $Masd=&mt('Modify another students data');
1.50 matthew 1506: $r->print(<<END);
1.52 matthew 1507: </p><p>
1.59 matthew 1508: <input type="hidden" name="action" value="modifystudent" />
1509: <input type="hidden" name="sortby" value="$sortby" />
1510: <input type="hidden" name="Status" value="$status" />
1.94 sakharuk 1511: <a href="javascript:document.studentform.submit();">$Masd</a>
1.50 matthew 1512: </body></html>
1513: END
1514: return;
1515: }
1516:
1517: sub get_enrollment_data {
1518: my ($sname,$sdomain) = @_;
1519: my $courseid = $ENV{'request.course.id'};
1520: $courseid =~ s:_:/:g;
1521: my %roles = &Apache::lonnet::dump('roles',$sdomain,$sname);
1522: my ($tmp) = keys(%roles);
1523: # Bail out if we were unable to get the students roles
1.87 matthew 1524: return ('error'.$tmp) if ($tmp =~ /^(con_lost|error|no_such_host)/i);
1.50 matthew 1525: # Go through the roles looking for enrollment in this course
1526: my ($end,$start) = (undef,undef);
1527: my $section = '';
1528: my $count = scalar(keys(%roles));
1529: while (my ($course,$role) = each(%roles)) {
1530: if ($course=~ /^\/$courseid\/*\s*(\w+)*_st$/ ) {
1531: #
1532: # Get active role
1533: $section=$1;
1534: (undef,$end,$start)=split(/\_/,$role);
1535: my $now=time;
1536: my $notactive=0;
1537: if ($start) {
1538: if ($now<$start) { $notactive=1; }
1539: }
1540: if ($end) {
1541: if ($now>$end) { $notactive=1; }
1542: }
1543: unless ($notactive) { return ($start,$end,$section); }
1544: }
1545: }
1546: return ($start,$end,$section);
1547: }
1548:
1.56 matthew 1549: #################################################
1550: #################################################
1551:
1552: =pod
1553:
1554: =item show_drop_list
1555:
1556: Display a list of students to drop
1557: Inputs:
1558:
1559: =over 4
1560:
1561: =item $r, Apache request
1562:
1563: =item $classlist, hash pointer returned from loncoursedata::get_classlist();
1564:
1565: =item $keylist, array pointer returned from loncoursedata::get_classlist()
1566: which describes the order elements are stored in the %$classlist values.
1567:
1568: =item $nosort, if true, sorting links are omitted.
1569:
1570: =back
1571:
1572: =cut
1573:
1574: #################################################
1575: #################################################
1.11 www 1576: sub show_drop_list {
1.56 matthew 1577: my ($r,$classlist,$keylist,$nosort)=@_;
1.11 www 1578: my $cid=$ENV{'request.course.id'};
1.59 matthew 1579: if (! exists($ENV{'form.sortby'})) {
1580: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1581: ['sortby']);
1582: }
1.54 matthew 1583: my $sortby = $ENV{'form.sortby'};
1584: if ($sortby !~ /^(username|domain|section|fullname|id)$/) {
1585: $sortby = 'username';
1586: }
1.56 matthew 1587: #
1.54 matthew 1588: my $action = "drop";
1589: $r->print(<<END);
1590: <input type="hidden" name="sortby" value="$sortby" />
1591: <input type="hidden" name="action" value="$action" />
1.50 matthew 1592: <input type="hidden" name="state" value="done" />
1.32 matthew 1593: <script>
1.51 matthew 1594: function checkAll(field) {
1.32 matthew 1595: for (i = 0; i < field.length; i++)
1596: field[i].checked = true ;
1597: }
1598:
1.51 matthew 1599: function uncheckAll(field) {
1.32 matthew 1600: for (i = 0; i < field.length; i++)
1601: field[i].checked = false ;
1602: }
1603: </script>
1604: <p>
1.26 matthew 1605: <input type="hidden" name="phase" value="four">
1.56 matthew 1606: END
1607:
1608: if ($nosort) {
1.94 sakharuk 1609: my %lt=&Apache::lonlocal::texthash(
1610: 'usrn' => "username",
1611: 'dom' => "domain",
1612: 'sn' => "student name",
1613: 'sec' => "section",
1614: );
1.56 matthew 1615: $r->print(<<END);
1616: <table border=2>
1617: <tr>
1618: <th> </th>
1.94 sakharuk 1619: <th>$lt{'usrn'}</th>
1620: <th>$lt{'dom'}</th>
1.56 matthew 1621: <th>ID</th>
1.94 sakharuk 1622: <th>$lt{'sn'}</th>
1623: <th>$lt{'sec'}</th>
1.56 matthew 1624: </tr>
1625: END
1626:
1627: } else {
1.94 sakharuk 1628: my %lt=&Apache::lonlocal::texthash(
1629: 'usrn' => "username",
1630: 'dom' => "domain",
1631: 'sn' => "student name",
1632: 'sec' => "section",
1633: );
1.56 matthew 1634: $r->print(<<END);
1.26 matthew 1635: <table border=2>
1.54 matthew 1636: <tr><th> </th>
1637: <th>
1.94 sakharuk 1638: <a href="/adm/dropadd?action=$action&sortby=username">$lt{'usrn'}</a>
1.54 matthew 1639: </th><th>
1.94 sakharuk 1640: <a href="/adm/dropadd?action=$action&sortby=domain">$lt{'dom'}</a>
1.54 matthew 1641: </th><th>
1642: <a href="/adm/dropadd?action=$action&sortby=id">ID</a>
1643: </th><th>
1.94 sakharuk 1644: <a href="/adm/dropadd?action=$action&sortby=fullname">$lt{'sn'}</a>
1.54 matthew 1645: </th><th>
1.94 sakharuk 1646: <a href="/adm/dropadd?action=$action&sortby=section">$lt{'sec'}</a>
1.54 matthew 1647: </th>
1648: </tr>
1.26 matthew 1649: END
1.56 matthew 1650: }
1651: #
1652: # Sort the students
1653: my %index;
1654: my $i;
1655: foreach (@$keylist) {
1656: $index{$_} = $i++;
1657: }
1658: my $index = $index{$sortby};
1659: my $second = $index{'username'};
1660: my $third = $index{'domain'};
1.54 matthew 1661: my @Sorted_Students = sort {
1.56 matthew 1662: lc($classlist->{$a}->[$index]) cmp lc($classlist->{$b}->[$index])
1663: ||
1664: lc($classlist->{$a}->[$second]) cmp lc($classlist->{$b}->[$second])
1665: ||
1666: lc($classlist->{$a}->[$third]) cmp lc($classlist->{$b}->[$third])
1667: } (keys(%$classlist));
1.54 matthew 1668: foreach my $student (@Sorted_Students) {
1.52 matthew 1669: my $error;
1.56 matthew 1670: my $username = $classlist->{$student}->[$index{'username'}];
1671: my $domain = $classlist->{$student}->[$index{'domain'}];
1672: my $section = $classlist->{$student}->[$index{'section'}];
1673: my $name = $classlist->{$student}->[$index{'fullname'}];
1674: my $id = $classlist->{$student}->[$index{'id'}];
1675: my $status = $classlist->{$student}->[$index{'status'}];
1.51 matthew 1676: next if ($status ne 'Active');
1677: #
1678: $r->print(<<"END");
1.26 matthew 1679: <tr>
1.51 matthew 1680: <td><input type="checkbox" name="droplist" value="$student"></td>
1681: <td>$username</td>
1682: <td>$domain</td>
1683: <td>$id</td>
1684: <td>$name</td>
1685: <td>$section</td>
1.26 matthew 1686: </tr>
1687: END
1.25 matthew 1688: }
1689: $r->print('</table><br>');
1.94 sakharuk 1690: my %lt=&Apache::lonlocal::texthash(
1691: 'dp' => "Drop Students",
1692: 'ca' => "check all",
1693: 'ua' => "uncheck all",
1694: );
1.32 matthew 1695: $r->print(<<"END");
1696: </p><p>
1.94 sakharuk 1697: <input type="button" value="$lt{'ca'}" onclick="javascript:checkAll(document.studentform.droplist)">
1698: <input type="button" value="$lt{'ua'}" onclick="javascript:uncheckAll(document.studentform.droplist)">
1699: <p><input type=submit value="$lt{'dp'}"></p>
1.32 matthew 1700: END
1.51 matthew 1701: return;
1.10 www 1702: }
1703:
1.48 matthew 1704: #
1705: # Print out the initial form to get the courselist file
1706: #
1707: sub print_first_courselist_upload_form {
1708: my $r=shift;
1.88 matthew 1709: my $str;
1710: $str = '<input type="hidden" name="phase" value="two">';
1711: $str .= '<input type="hidden" name="action" value="upload" />';
1712: $str .= '<input type="hidden" name="state" value="got_file" />';
1713: $str .= "<h3>".&mt('Upload a class list')."</h3>\n";
1714: $str .= &Apache::loncommon::upfile_select_html();
1715: $str .= "<p>\n";
1716: $str .= '<input type="submit" name="fileupload" value="'.
1717: &mt('Upload class list').'">'."\n";
1718: $str .= '<input type="checkbox" name="noFirstLine" /> '.
1719: &mt('Ignore First Line')."</p>\n";
1720: $str .= &Apache::loncommon::help_open_topic("Course_Create_Class_List",
1.92 sakharuk 1721: &mt("How do I create a class list from a spreadsheet")).
1.88 matthew 1722: "<br />\n";
1723: $str .= &Apache::loncommon::help_open_topic("Course_Convert_To_CSV",
1.92 sakharuk 1724: &mt("How do I create a CSV file from a spreadsheet")).
1.88 matthew 1725: "<br />\n";
1726: $str .= "</body>\n</html>\n";
1727: $r->print($str);
1.48 matthew 1728: return;
1729: }
1730:
1.10 www 1731: # ================================================= Drop/Add from uploaded file
1732: sub upfile_drop_add {
1733: my $r=shift;
1.24 albertel 1734: &Apache::loncommon::load_tmp_file($r);
1735: my @studentdata=&Apache::loncommon::upfile_record_sep();
1.82 www 1736: if($ENV{'form.noFirstLine'}){shift(@studentdata);}
1.26 matthew 1737: my @keyfields = split(/\,/,$ENV{'form.keyfields'});
1738: my $cid = $ENV{'request.course.id'};
1.25 matthew 1739: my %fields=();
1.26 matthew 1740: for (my $i=0; $i<=$ENV{'form.nfields'}; $i++) {
1.25 matthew 1741: if ($ENV{'form.upfile_associate'} eq 'reverse') {
1742: if ($ENV{'form.f'.$i} ne 'none') {
1743: $fields{$keyfields[$i]}=$ENV{'form.f'.$i};
1744: }
1745: } else {
1746: $fields{$ENV{'form.f'.$i}}=$keyfields[$i];
1747: }
1748: }
1.26 matthew 1749: #
1.68 matthew 1750: my ($startdate,$enddate) = &get_dates_from_form();
1751: if ($ENV{'form.makedatesdefault'}) {
1752: $r->print(&make_dates_default($startdate,$enddate));
1753: }
1.31 matthew 1754: # Determine domain and desired host (home server)
1.25 matthew 1755: my $domain=$ENV{'form.lcdomain'};
1.31 matthew 1756: my $desiredhost = $ENV{'form.lcserver'};
1757: if (lc($desiredhost) eq 'default') {
1758: $desiredhost = undef;
1759: } else {
1.45 matthew 1760: my %home_servers = &Apache::loncommon::get_library_servers($domain);
1.31 matthew 1761: if (! exists($home_servers{$desiredhost})) {
1.88 matthew 1762: $r->print('<font color="#ff0000">'.&mt('Error').'</font>'.
1763: &mt('Invalid home server specified'));
1764: $r->print("</body>\n</html>\n");
1.31 matthew 1765: return;
1766: }
1767: }
1.26 matthew 1768: # Determine authentication mechanism
1769: my $amode = '';
1770: my $genpwd = '';
1.25 matthew 1771: if ($ENV{'form.login'} eq 'krb') {
1.47 albertel 1772: $amode='krb';
1773: $amode.=$ENV{'form.krbver'};
1.28 matthew 1774: $genpwd=$ENV{'form.krbarg'};
1.25 matthew 1775: } elsif ($ENV{'form.login'} eq 'int') {
1776: $amode='internal';
1.28 matthew 1777: if ((defined($ENV{'form.intarg'})) && ($ENV{'form.intarg'})) {
1778: $genpwd=$ENV{'form.intarg'};
1.25 matthew 1779: }
1780: } elsif ($ENV{'form.login'} eq 'loc') {
1781: $amode='localauth';
1782: if ((defined($ENV{'form.locarg'})) && ($ENV{'form.locarg'})) {
1783: $genpwd=$ENV{'form.locarg'};
1.79 matthew 1784: }
1785: }
1786: if ($amode =~ /^krb/) {
1787: if (! defined($genpwd) || $genpwd eq '') {
1788: $r->print('<font color="red" size="+1">'.
1.88 matthew 1789: &mt('Unable to enroll students').'</font> '.
1790: &mt('No Kerberos domain was specified.').'</p>');
1.79 matthew 1791: $amode = ''; # This causes the loop below to be skipped
1.25 matthew 1792: }
1793: }
1794: unless (($domain=~/\W/) || ($amode eq '')) {
1.26 matthew 1795: #######################################
1796: ## Enroll Students ##
1797: #######################################
1.88 matthew 1798: $r->print('<h3>'.&mt('Enrolling Students')."</h3>\n<p>\n");
1.25 matthew 1799: my $count=0;
1800: my $flushc=0;
1801: my %student=();
1.26 matthew 1802: # Get new classlist
1.25 matthew 1803: foreach (@studentdata) {
1804: my %entries=&Apache::loncommon::record_sep($_);
1.26 matthew 1805: # Determine student name
1.25 matthew 1806: unless (($entries{$fields{'username'}} eq '') ||
1807: (!defined($entries{$fields{'username'}}))) {
1.26 matthew 1808: my ($fname, $mname, $lname,$gen) = ('','','','');
1.25 matthew 1809: if (defined($fields{'names'})) {
1.26 matthew 1810: ($lname,$fname,$mname)=($entries{$fields{'names'}}=~
1811: /([^\,]+)\,\s*(\w+)\s*(.*)$/);
1.25 matthew 1812: } else {
1813: if (defined($fields{'fname'})) {
1814: $fname=$entries{$fields{'fname'}};
1815: }
1816: if (defined($fields{'mname'})) {
1817: $mname=$entries{$fields{'mname'}};
1818: }
1819: if (defined($fields{'lname'})) {
1820: $lname=$entries{$fields{'lname'}};
1821: }
1822: if (defined($fields{'gen'})) {
1823: $gen=$entries{$fields{'gen'}};
1824: }
1825: }
1826: if ($entries{$fields{'username'}}=~/\W/) {
1.88 matthew 1827: $r->print('<br />'.
1828: &mt('<b>[_1]</b>: Unacceptable username for user [_2] [_3] [_4] [_5]',
1829: $entries{$fields{'username'}},$fname,$mname,$lname,$gen).
1830: '</b>');
1.25 matthew 1831: } else {
1.26 matthew 1832: # determine section number
1.25 matthew 1833: my $sec='';
1834: my $username=$entries{$fields{'username'}};
1835: if (defined($fields{'sec'})) {
1836: if (defined($entries{$fields{'sec'}})) {
1837: $sec=$entries{$fields{'sec'}};
1838: }
1839: }
1.80 matthew 1840: # remove non alphanumeric values from section
1841: $sec =~ s/\W//g;
1.26 matthew 1842: # determine student id number
1.25 matthew 1843: my $id='';
1844: if (defined($fields{'id'})) {
1845: if (defined($entries{$fields{'id'}})) {
1846: $id=$entries{$fields{'id'}};
1847: }
1848: $id=~tr/A-Z/a-z/;
1849: }
1.73 www 1850: # determine email address
1851: my $email='';
1852: if (defined($fields{'email'})) {
1853: if (defined($entries{$fields{'email'}})) {
1854: $email=$entries{$fields{'email'}};
1855: unless ($email=~/^[^\@]+\@[^\@]+$/) { $email=''; }
1856: }
1857: }
1.26 matthew 1858: # determine student password
1.25 matthew 1859: my $password='';
1860: if ($genpwd) {
1861: $password=$genpwd;
1862: } else {
1863: if (defined($fields{'ipwd'})) {
1864: if ($entries{$fields{'ipwd'}}) {
1865: $password=$entries{$fields{'ipwd'}};
1866: }
1867: }
1868: }
1.56 matthew 1869: # Clean up whitespace
1870: foreach (\$domain,\$username,\$id,\$fname,\$mname,
1871: \$lname,\$gen,\$sec) {
1872: $$_ =~ s/(\s+$|^\s+)//g;
1873: }
1.84 albertel 1874: if ($password || $ENV{'form.login'} eq 'loc') {
1.33 matthew 1875: &modifystudent($domain,$username,$cid,$sec,
1876: $desiredhost);
1.25 matthew 1877: my $reply=&Apache::lonnet::modifystudent
1878: ($domain,$username,$id,$amode,$password,
1879: $fname,$mname,$lname,$gen,$sec,$enddate,
1.73 www 1880: $startdate,$ENV{'form.forceid'},$desiredhost,
1881: $email);
1.26 matthew 1882: if ($reply ne 'ok') {
1.72 matthew 1883: $reply =~ s/^error://;
1.88 matthew 1884: $r->print('<br />'.
1885: &mt('<b>[_1]</b>: Unable to enroll: [_2]',$username,$reply));
1.10 www 1886: } else {
1.7 www 1887: $count++; $flushc++;
1888: $student{$username}=1;
1.6 www 1889: $r->print('. ');
1.7 www 1890: if ($flushc>15) {
1891: $r->rflush;
1892: $flushc=0;
1893: }
1.6 www 1894: }
1.25 matthew 1895: } else {
1.88 matthew 1896: $r->print('<br />'.
1897: &mt('<b>[_1]</b>: Unable to enroll. No password specified.',$username)
1898: );
1.25 matthew 1899: }
1900: }
1.26 matthew 1901: }
1902: } # end of foreach (@studentdata)
1.88 matthew 1903: $r->print("</p>\n<p>\n".&mt('Processed [_1] student(s).',$count).
1904: "</p>\n");
1905: $r->print("<p>\n".
1906: &mt('If active, the new role will be available when the '.
1907: 'students next log in to LON-CAPA.')."</p>\n");
1.26 matthew 1908: #####################################
1909: # Drop students #
1910: #####################################
1.25 matthew 1911: if ($ENV{'form.fullup'} eq 'yes') {
1.88 matthew 1912: $r->print('<h3>'.&mt('Dropping Students')."</h3>\n");
1.26 matthew 1913: # Get current classlist
1.56 matthew 1914: my ($classlist,$keylist)=&Apache::loncoursedata::get_classlist();
1915: if (! defined($classlist)) {
1.88 matthew 1916: $r->print(&mt('There are no students currently enrolled.').
1917: "\n");
1.56 matthew 1918: } else {
1919: # Remove the students we just added from the list of students.
1.25 matthew 1920: foreach (@studentdata) {
1921: my %entries=&Apache::loncommon::record_sep($_);
1922: unless (($entries{$fields{'username'}} eq '') ||
1923: (!defined($entries{$fields{'username'}}))) {
1.56 matthew 1924: delete($classlist->{$entries{$fields{'username'}}.
1.26 matthew 1925: ':'.$domain});
1.25 matthew 1926: }
1927: }
1.56 matthew 1928: # Print out list of dropped students.
1929: &show_drop_list($r,$classlist,$keylist,'nosort');
1.25 matthew 1930: }
1931: }
1.26 matthew 1932: } # end of unless
1.10 www 1933: }
1934:
1.11 www 1935: # ================================================================== Phase four
1936: sub drop_student_list {
1937: my $r=shift;
1938: my $count=0;
1.35 matthew 1939: my @droplist;
1940: if (ref($ENV{'form.droplist'})) {
1941: @droplist = @{$ENV{'form.droplist'}};
1942: } else {
1943: @droplist = ($ENV{'form.droplist'});
1944: }
1945: foreach (@droplist) {
1.26 matthew 1946: my ($uname,$udom)=split(/\:/,$_);
1.56 matthew 1947: # drop student
1.35 matthew 1948: my $result = &modifystudent($udom,$uname,$ENV{'request.course.id'});
1.37 matthew 1949: if ($result eq 'ok' || $result eq 'ok:') {
1.88 matthew 1950: $r->print(&mt('Dropped [_1]',$uname.'@'.$udom).'<br>');
1.59 matthew 1951: $count++;
1.35 matthew 1952: } else {
1.88 matthew 1953: $r->print(
1954: &mt('Error dropping [_1]:[_2]',$uname.'@'.$udom,$result).
1.35 matthew 1955: '<br />');
1956: }
1.20 harris41 1957: }
1.88 matthew 1958: $r->print('<p><b>'.&mt('Dropped [_1] student(s).',$count).'</b></p>');
1959: $r->print('<p>'.&mt('Re-enrollment will re-activate data.')) if ($count);
1.11 www 1960: }
1961:
1.50 matthew 1962: ###################################################################
1963: ###################################################################
1964:
1965: =pod
1966:
1967: =item &handler
1968:
1969: The typical handler you see in all these modules. Takes $r, the
1970: http request, as an argument.
1971:
1972: The response to the request is governed by two form variables
1973:
1974: form.action form.state response
1975: ---------------------------------------------------
1976: undefined undefined print main menu
1977: upload undefined print courselist upload menu
1978: upload got_file deal with uploaded file,
1979: print the upload managing menu
1980: upload enrolling enroll students based on upload
1981: drop undefined print the classlist ready to drop
1982: drop done drop the selected students
1.74 matthew 1983: enrollstudent undefined print student username domain form
1984: enrollstudent gotusername print single student enroll menu
1.50 matthew 1985: enrollstudent enrolling enroll student
1986: classlist undefined print html classlist
1987: classlist csv print csv classlist
1988: modifystudent undefined print classlist to select student to modify
1989: modifystudent selected print modify student menu
1990: modifystudent done make modifications to student record
1991:
1992: =cut
1993:
1994: ###################################################################
1995: ###################################################################
1.10 www 1996: sub handler {
1.26 matthew 1997: my $r=shift;
1998: if ($r->header_only) {
1.86 www 1999: &Apache::loncommon::content_type($r,'text/html');
1.26 matthew 2000: $r->send_http_header;
2001: return OK;
2002: }
1.48 matthew 2003: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.50 matthew 2004: ['action','state']);
1.26 matthew 2005: # Needs to be in a course
1.50 matthew 2006: if (! (($ENV{'request.course.fn'}) &&
2007: (&Apache::lonnet::allowed('cst',$ENV{'request.course.id'})))) {
2008: # Not in a course, or not allowed to modify parms
2009: $ENV{'user.error.msg'}=
2010: "/adm/dropadd:cst:0:0:Cannot drop or add students";
2011: return HTTP_NOT_ACCEPTABLE;
2012: }
2013: #
2014: # Only output the header information if they did not request csv format
2015: #
2016: if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) {
2017: $r->content_type('text/csv');
2018: } else {
1.26 matthew 2019: # Start page
1.86 www 2020: &Apache::loncommon::content_type($r,'text/html');
1.26 matthew 2021: $r->send_http_header;
1.50 matthew 2022: $r->print(&header());
2023: }
2024: #
2025: # Main switch on form.action and form.state, as appropriate
2026: if (! exists($ENV{'form.action'})) {
2027: &print_main_menu($r);
2028: } elsif ($ENV{'form.action'} eq 'upload') {
2029: if (! exists($ENV{'form.state'})) {
2030: &print_first_courselist_upload_form($r);
2031: } elsif ($ENV{'form.state'} eq 'got_file') {
2032: &print_upload_manager_form($r);
2033: } elsif ($ENV{'form.state'} eq 'enrolling') {
1.26 matthew 2034: if ($ENV{'form.datatoken'}) {
2035: &upfile_drop_add($r);
1.50 matthew 2036: } else {
2037: # Hmmm, this is an error
1.26 matthew 2038: }
1.50 matthew 2039: } else {
2040: &print_first_courselist_upload_form($r);
1.26 matthew 2041: }
1.50 matthew 2042: } elsif ($ENV{'form.action'} eq 'drop') {
2043: if (! exists($ENV{'form.state'})) {
1.51 matthew 2044: &print_drop_menu($r);
1.50 matthew 2045: } elsif ($ENV{'form.state'} eq 'done') {
1.26 matthew 2046: &drop_student_list($r);
1.50 matthew 2047: } else {
1.55 matthew 2048: &print_drop_menu($r);
1.26 matthew 2049: }
1.50 matthew 2050: } elsif ($ENV{'form.action'} eq 'enrollstudent') {
2051: if (! exists($ENV{'form.state'})) {
1.74 matthew 2052: &get_student_username_domain_form($r);
2053: } elsif ($ENV{'form.state'} eq 'gotusername') {
1.50 matthew 2054: &print_enroll_single_student_form($r);
2055: } elsif ($ENV{'form.state'} eq 'enrolling') {
1.26 matthew 2056: &enroll_single_student($r);
1.50 matthew 2057: } else {
1.74 matthew 2058: &get_student_username_domain_form($r);
1.26 matthew 2059: }
1.50 matthew 2060: } elsif ($ENV{'form.action'} eq 'classlist') {
2061: if (! exists($ENV{'form.state'})) {
2062: &print_html_classlist($r);
2063: } elsif ($ENV{'form.state'} eq 'csv') {
1.60 matthew 2064: &print_formatted_classlist($r,'csv');
2065: } elsif ($ENV{'form.state'} eq 'excel') {
2066: &print_formatted_classlist($r,'excel');
1.50 matthew 2067: } else {
2068: &print_html_classlist($r);
2069: }
2070: } elsif ($ENV{'form.action'} eq 'modifystudent') {
2071: if (! exists($ENV{'form.state'})) {
2072: &print_html_classlist($r);
2073: } elsif ($ENV{'form.state'} eq 'selected') {
2074: &print_modify_student_form($r);
2075: } elsif ($ENV{'form.state'} eq 'done') {
2076: &modify_single_student($r);
2077: } else {
2078: &print_html_classlist($r);
2079: }
2080: } else {
2081: # We should not end up here, but I guess it is possible
2082: &Apache::lonnet::logthis("Undetermined state in londropadd.pm. ".
2083: "form.action = ".$ENV{'form.action'}.
2084: "Someone should fix this.");
2085: &print_main_menu($r);
2086: }
2087: #
2088: # Finish up
2089: if (exists($ENV{'form.state'}) && ($ENV{'form.state'} eq 'csv')) {
2090: $r->print("\n");
1.26 matthew 2091: } else {
1.50 matthew 2092: $r->print('</form></body></html>');
1.26 matthew 2093: }
2094: return OK;
1.1 www 2095: }
2096:
1.50 matthew 2097: ###################################################################
2098: ###################################################################
2099:
1.1 www 2100: 1;
2101: __END__
1.50 matthew 2102:
1.1 www 2103:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>