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