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