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