Annotation of loncom/interface/lonstatistics.pm, revision 1.63
1.1 albertel 1: # The LearningOnline Network with CAPA
2: #
1.63 ! matthew 3: # $Id: lonstatistics.pm,v 1.62 2003/02/28 21:19:53 matthew Exp $
1.1 albertel 4: #
5: # Copyright Michigan State University Board of Trustees
6: #
7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
8: #
9: # LON-CAPA is free software; you can redistribute it and/or modify
10: # it under the terms of the GNU General Public License as published by
11: # the Free Software Foundation; either version 2 of the License, or
12: # (at your option) any later version.
13: #
14: # LON-CAPA is distributed in the hope that it will be useful,
15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: # GNU General Public License for more details.
18: #
19: # You should have received a copy of the GNU General Public License
20: # along with LON-CAPA; if not, write to the Free Software
21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22: #
23: # /home/httpd/html/adm/gpl.txt
24: #
25: # http://www.lon-capa.org/
26: #
27: # (Navigate problems for statistical reports
1.14 minaeibi 28: #
1.1 albertel 29: ###
30:
1.59 matthew 31: =pod
32:
33: =head1 NAME
34:
35: lonstatistics
36:
37: =head1 SYNOPSIS
38:
39: Main handler for statistics and chart.
40:
41: =head1 PACKAGES USED
42:
1.60 matthew 43: use strict;
44: use Apache::Constants qw(:common :http);
45: use Apache::lonnet();
46: use Apache::lonhomework;
47: use Apache::loncommon;
48: use Apache::loncoursedata;
49: use Apache::lonhtmlcommon;
50: use Apache::lonproblemanalysis;
51: use Apache::lonproblemstatistics;
52: use Apache::lonstudentassessment;
53: use Apache::lonpercentage;
54: use GDBM_File;
1.59 matthew 55:
56: =over 4
57:
58: =cut
59:
1.55 minaeibi 60: package Apache::lonstatistics;
1.1 albertel 61:
1.30 stredwic 62: use strict;
1.1 albertel 63: use Apache::Constants qw(:common :http);
1.61 matthew 64: use vars qw(
65: @FullClasslist
66: @Students
67: @Sections
68: @SelectedSections
69: %StudentData
70: @StudentDataOrder
71: @SelectedStudentData
72: $top_map
73: @Sequences
74: @SelectedMaps
75: @Assessments);
76:
1.1 albertel 77: use Apache::lonnet();
78: use Apache::lonhomework;
1.12 minaeibi 79: use Apache::loncommon;
1.29 stredwic 80: use Apache::loncoursedata;
81: use Apache::lonhtmlcommon;
1.61 matthew 82: use Apache::lonproblemanalysis();
83: use Apache::lonproblemstatistics();
84: use Apache::lonstudentassessment();
1.49 stredwic 85: use Apache::lonpercentage;
1.1 albertel 86: use GDBM_File;
87:
1.60 matthew 88:
89: #######################################################
90: #######################################################
91:
92: =pod
93:
94: =item Package Variables
95:
96: =item @FullClasslist The full classlist
97:
98: =item @Students The students we are concerned with for this invocation
99:
100: =item @Sections The sections available in this class
101:
102: =item $curr_student The student currently being examined
103:
104: =item $prev_student The student previous in the classlist
105:
106: =item $next_student The student next in the classlist
107:
108: =over
109:
110: =cut
111:
112: #######################################################
113: #######################################################
114: #
115: # Classlist variables
116: #
1.59 matthew 117: my $curr_student;
118: my $prev_student;
119: my $next_student;
120:
121: #######################################################
122: #######################################################
123:
124: =pod
125:
126: =item &clear_classlist_variables()
127:
128: undef the following package variables:
129:
130: =over
131:
1.60 matthew 132: =item @FullClasslist
133:
134: =item @Students
1.59 matthew 135:
1.60 matthew 136: =item @Sections
1.59 matthew 137:
1.60 matthew 138: =item @SelectedSections
1.59 matthew 139:
1.61 matthew 140: =item %StudentData
141:
142: =item @StudentDataOrder
143:
144: =item @SelectedStudentData
145:
1.60 matthew 146: =item $curr_student
1.59 matthew 147:
1.60 matthew 148: =item $prev_student
1.59 matthew 149:
1.60 matthew 150: =item $next_student
1.59 matthew 151:
152: =back
153:
154: =cut
155:
156: #######################################################
157: #######################################################
158: sub clear_classlist_variables {
159: undef(@FullClasslist);
160: undef(@Students);
161: undef(@Sections);
1.60 matthew 162: undef(@SelectedSections);
1.61 matthew 163: undef(%StudentData);
164: undef(@SelectedStudentData);
1.59 matthew 165: undef($curr_student);
166: undef($prev_student);
167: undef($next_student);
168: }
169:
170: #######################################################
171: #######################################################
172:
173: =pod
174:
175: =item &PrepareClasslist()
176:
177: Build up the classlist information. The classlist information is kept in
178: the following package variables:
179:
180: =over
181:
1.60 matthew 182: =item @FullClasslist
183:
184: =item @Students
1.59 matthew 185:
1.60 matthew 186: =item @Sections
1.59 matthew 187:
1.60 matthew 188: =item @SelectedSections
1.59 matthew 189:
1.61 matthew 190: =item %StudentData
191:
192: =item @SelectedStudentData
193:
1.60 matthew 194: =item $curr_student
1.59 matthew 195:
1.60 matthew 196: =item $prev_student
1.59 matthew 197:
1.60 matthew 198: =item $next_student
1.59 matthew 199:
200: =back
201:
202: $curr_student, $prev_student, and $next_student may not be defined, depending
203: upon the calling context.
204:
205: =cut
206:
207: #######################################################
208: #######################################################
209: sub PrepareClasslist {
210: my $r = shift;
211: my %Sections;
212: &clear_classlist_variables();
213: #
214: # Retrieve the classlist
215: my $cid = $ENV{'request.course.id'};
216: my $cdom = $ENV{'course.'.$cid.'.domain'};
217: my $cnum = $ENV{'course.'.$cid.'.num'};
218: my ($classlist,$field_names) = &Apache::loncoursedata::get_classlist($cid,
219: $cdom,$cnum);
1.60 matthew 220: if (exists($ENV{'form.Section'})) {
1.59 matthew 221: if (ref($ENV{'form.Section'})) {
1.61 matthew 222: @SelectedSections = @{$ENV{'form.Section'}};
223: } elsif ($ENV{'form.Section'} !~ /^\s*$/) {
224: @SelectedSections = ($ENV{'form.Section'});
225: }
226: }
227: @SelectedSections = ('all') if (! @SelectedSections);
228: foreach (@SelectedSections) {
229: if ($_ eq 'all') {
230: @SelectedSections = ('all');
1.59 matthew 231: }
232: }
1.61 matthew 233: #
234: # Set up %StudentData
235: @StudentDataOrder = qw/fullname username domain id section status/;
236: foreach my $field (@StudentDataOrder) {
237: $StudentData{$field}->{'title'} = $field;
1.63 ! matthew 238: $StudentData{$field}->{'base_width'} = length($field);
1.61 matthew 239: $StudentData{$field}->{'width'} =
240: $StudentData{$field}->{'base_width'};
241: }
242:
1.59 matthew 243: #
244: # Process the classlist
245: while (my ($student,$student_data) = each (%$classlist)) {
246: my $studenthash = ();
247: for (my $i=0; $i< scalar(@$field_names);$i++) {
1.61 matthew 248: my $field = $field_names->[$i];
249: # Store the data
250: $studenthash->{$field}=$student_data->[$i];
251: # Keep track of the width of the fields
252: next if (! exists($StudentData{$field}));
1.63 ! matthew 253: my $length = length($student_data->[$i]);
1.61 matthew 254: if ($StudentData{$field}->{'width'} < $length) {
255: $StudentData{$field}->{'width'} = $length;
256: }
1.59 matthew 257: }
258: push (@FullClasslist,$studenthash);
259: #
260: # Build up a list of sections
261: my $section = $studenthash->{'section'};
1.60 matthew 262: if (! defined($section) || $section =~/^\s*$/ || $section == -1) {
263: $studenthash->{'section'} = 'none';
264: $section = $studenthash->{'section'};
265: }
1.59 matthew 266: $Sections{$section}++;
267: #
268: # Only put in the list those students we are interested in
1.60 matthew 269: foreach my $sect (@SelectedSections) {
1.61 matthew 270: if (($sect eq 'all') || ($section eq $sect)) {
1.60 matthew 271: push (@Students,$studenthash);
272: last;
273: }
1.59 matthew 274: }
275: }
276: #
277: # Put the consolidated section data in the right place
1.60 matthew 278: @Sections = sort {$a cmp $b} keys(%Sections);
1.61 matthew 279: unshift(@Sections,'all'); # Put 'all' at the front of the list
1.59 matthew 280: #
281: # Sort the Students
282: my $sortby = 'fullname';
1.60 matthew 283: $sortby = $ENV{'form.sort'} if (exists($ENV{'form.sort'}));
284: my @TmpStudents = sort { $a->{$sortby} cmp $b->{$sortby} ||
285: $a->{'fullname'} cmp $b->{'fullname'} } @Students;
286: @Students = @TmpStudents;
1.59 matthew 287: #
288: # Now deal with that current student thing....
289: if (exists($ENV{'form.StudentAssessmentStudent'})) {
290: my ($current_uname,$current_dom) =
291: split(':',$ENV{'form.StudentAssessmentStudent'});
292: my $i;
293: for ($i = 0; $i<=$#Students; $i++) {
294: next if (($Students[$i]->{'username'} ne $current_uname) ||
295: ($Students[$i]->{'domain'} ne $current_dom));
1.60 matthew 296: $curr_student = $Students[$i];
1.59 matthew 297: last; # If we get here, we have our student.
298: }
299: if ($i == 0) {
300: $prev_student = 'none';
301: } else {
302: $prev_student = $Students[$i-1];
303: }
304: if ($i == $#Students) {
305: $next_student = 'none';
306: } else {
307: $next_student = $Students[$i+1];
308: }
309: }
1.61 matthew 310: #
311: if (exists($ENV{'form.StudentData'})) {
312: if (ref($ENV{'form.StudentData'}) eq 'ARRAY') {
313: @SelectedStudentData = @{$ENV{'form.StudentData'}};
314: } else {
315: @SelectedStudentData = ($ENV{'form.StudentData'});
316: }
317: } else {
318: @SelectedStudentData = ('fullname');
319: }
320: foreach (@SelectedStudentData) {
321: if ($_ eq 'all') {
322: @SelectedStudentData = ('all');
323: last;
324: }
325: }
326: #
327: return;
328: }
329:
330: #######################################################
331: #######################################################
332:
333: =pod
334:
335: =item ¤t_student()
336:
337: Returns a pointer to a hash containing data about the currently
338: selected student.
339:
340: =cut
341:
342: #######################################################
343: #######################################################
344: sub current_student {
345: if (defined($curr_student)) {
346: return $curr_student;
347: } else {
348: return 'All Students';
349: }
350: }
351:
352: #######################################################
353: #######################################################
354:
355: =pod
356:
357: =item &previous_student()
358:
359: Returns a pointer to a hash containing data about the student prior
360: in the list of students. Or something.
361:
362: =cut
363:
364: #######################################################
365: #######################################################
366: sub previous_student {
367: if (defined($prev_student)) {
368: return $prev_student;
369: } else {
370: return 'No Student Selected';
371: }
1.59 matthew 372: }
373:
374: #######################################################
375: #######################################################
1.61 matthew 376:
377: =pod
378:
379: =item &next_student()
380:
381: Returns a pointer to a hash containing data about the next student
382: to be viewed.
383:
384: =cut
385:
386: #######################################################
387: #######################################################
388: sub next_student {
389: if (defined($next_student)) {
390: return $next_student;
391: } else {
392: return 'No Student Selected';
393: }
394: }
1.60 matthew 395:
396: #######################################################
397: #######################################################
398:
399: =pod
400:
401: =item &clear_sequence_variables()
402:
403: =cut
404:
405: #######################################################
406: #######################################################
407: sub clear_sequence_variables {
408: undef($top_map);
409: undef(@Sequences);
410: undef(@Assessments);
411: }
412:
413: #######################################################
414: #######################################################
415:
416: =pod
417:
1.61 matthew 418: =item &SetSelectedMaps($elementname)
419:
420: Sets the @SelectedMaps array from $ENV{'form.'.$elementname};
421:
422: =cut
423:
424: #######################################################
425: #######################################################
426: sub SetSelectedMaps {
427: my $elementname = shift;
428: if (exists($ENV{'form.'.$elementname})) {
429: if (ref($ENV{'form.'.$elementname})) {
430: @SelectedMaps = @{$ENV{'form.'.$elementname}};
431: } else {
432: @SelectedMaps = ($ENV{'form.'.$elementname});
433: }
434: } else {
435: @SelectedMaps = ('all');
436: }
437: }
438:
439: #######################################################
440: #######################################################
441:
442: =pod
443:
1.60 matthew 444: =item &PrepareCourseData($r)
445:
446: =cut
447:
448: #######################################################
449: #######################################################
450: sub PrepareCourseData {
451: my ($r) = @_;
452: &clear_sequence_variables();
1.61 matthew 453: my ($top,$sequences,$assessments) =
454: &Apache::loncoursedata::get_sequence_assessment_data();
1.60 matthew 455: if (! defined($top) || ! ref($top)) {
456: # There has been an error, better report it
457: &Apache::lonnet::logthis('top is undefined');
458: return;
459: }
460: $top_map = $top if (ref($top));
461: @Sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');
1.61 matthew 462: @Assessments = @{$assessments} if (ref($assessments) eq 'ARRAY');
463: #
464: # Compute column widths
465: foreach my $seq (@Sequences) {
1.63 ! matthew 466: my $name_length = length($seq->{'title'});
1.61 matthew 467: my $num_parts = $seq->{'num_assess_parts'};
468: #
469: # The number of columns needed for the summation text:
470: # " 1/5" = 1+3 columns, " 10/99" = 1+5 columns
1.63 ! matthew 471: my $sum_length = 1+1+2*(length($num_parts));
1.61 matthew 472: my $num_col = $num_parts+$sum_length;
473: if ($num_col < $name_length) {
474: $num_col = $name_length;
475: }
476: $seq->{'base_width'} = $name_length;
477: $seq->{'width'} = $num_col;
478: }
479: return;
480: }
481:
482: #######################################################
483: #######################################################
1.60 matthew 484:
485: =pod
486:
1.61 matthew 487: =item &log_sequence($sequence,$recursive,$padding)
488:
489: Write data about the sequence to a logfile. If $recursive is not
490: undef the data is written recursively. $padding is used for recursive
491: calls.
492:
493: =cut
494:
495: #######################################################
496: #######################################################
497: sub log_sequence {
498: my ($seq,$recursive,$padding) = @_;
499: $padding = '' if (! defined($padding));
500: if (ref($seq) ne 'HASH') {
501: &Apache::lonnet::logthis('log_sequence passed bad sequnce');
502: return;
503: }
504: &Apache::lonnet::logthis($padding.'sequence '.$seq->{'title'});
505: while (my($key,$value) = each(%$seq)) {
506: next if ($key eq 'contents');
507: if (ref($value) eq 'ARRAY') {
508: for (my $i=0;$i< scalar(@$value);$i++) {
509: &Apache::lonnet::logthis($padding.$key.'['.$i.']='.
510: $value->[$i]);
511: }
512: } else {
513: &Apache::lonnet::logthis($padding.$key.'='.$value);
514: }
515: }
516: if (defined($recursive)) {
517: &Apache::lonnet::logthis($padding.'-'x20);
518: &Apache::lonnet::logthis($padding.'contains:');
519: foreach my $item (@{$seq->{'contents'}}) {
520: if ($item->{'type'} eq 'container') {
521: &log_sequence($item,$recursive,$padding.' ');
522: } else {
523: &Apache::lonnet::logthis($padding.'title = '.$item->{'title'});
524: while (my($key,$value) = each(%$item)) {
525: next if ($key eq 'title');
526: if (ref($value) eq 'ARRAY') {
527: for (my $i=0;$i< scalar(@$value);$i++) {
528: &Apache::lonnet::logthis($padding.$key.'['.$i.']='.
529: $value->[$i]);
530: }
531: } else {
532: &Apache::lonnet::logthis($padding.$key.'='.$value);
533: }
534: }
535: }
1.60 matthew 536: }
1.61 matthew 537: &Apache::lonnet::logthis($padding.'end contents of '.$seq->{'title'});
538: &Apache::lonnet::logthis($padding.'-'x20);
1.60 matthew 539: }
1.61 matthew 540: return;
541: }
542:
543: ##############################################
544: ##############################################
545:
546: =pod
547:
548: =item &StudentDataSelect($elementname,$status,$numvisible,$selected)
549:
550: Returns html for a selection box allowing the user to choose one (or more)
551: of the fields of student data available (fullname, username, id, section, etc)
552:
553: =over 4
554:
555: =item $elementname The name of the HTML form element
556:
557: =item $status 'multiple' or 'single' selection box
558:
559: =item $numvisible The number of options to be visible
560:
561: =back
1.60 matthew 562:
563: =cut
564:
1.61 matthew 565: ##############################################
566: ##############################################
567: sub StudentDataSelect {
568: my ($elementname,$status,$numvisible)=@_;
569: if ($numvisible < 1) {
570: return;
571: }
572: #
573: # Build the form element
574: my $Str = "\n";
575: $Str .= '<select name="'.$elementname.'" ';
576: if ($status ne 'single') {
577: $Str .= 'multiple="true" ';
578: }
579: $Str .= 'size="'.$numvisible.'" >'."\n";
580: #
581: # Deal with 'all'
582: $Str .= ' <option value="all" ';
583: foreach (@SelectedStudentData) {
584: if ($_ eq 'all') {
585: $Str .= 'selected ';
586: last;
587: }
588: }
589: $Str .= ">all</option>\n";
590: #
591: # Loop through the student data fields
592: foreach my $item (@StudentDataOrder) {
593: $Str .= ' <option value="'.$item.'" ';
594: foreach (@SelectedStudentData) {
595: if ($item eq $_ ) {
596: $Str .= 'selected ';
597: last;
598: }
599: }
600: $Str .= '>'.$item."</option>\n";
601: }
602: $Str .= "</select>\n";
603: return $Str;
1.60 matthew 604: }
605:
606: ##############################################
607: ##############################################
608:
609: =pod
610:
1.61 matthew 611: =item &MapSelect($elementname,$status,$numvisible,$restriction)
1.60 matthew 612:
613: Returns html for a selection box allowing the user to choose one (or more)
614: of the sequences in the course. The values of the sequences are the symbs.
615: If the top sequence is selected, the value 'top' will result.
616:
617: =over 4
618:
619: =item $elementname The name of the HTML form element
620:
621: =item $status 'multiple' or 'single' selection box
622:
623: =item $numvisible The number of options to be visible
624:
625: =item $restriction Code reference to subroutine which returns true or
626: false. The code must expect a reference to a sequence data structure.
627:
628: =back
629:
630: =cut
631:
632: ##############################################
633: ##############################################
634: sub MapSelect {
1.61 matthew 635: my ($elementname,$status,$numvisible,$restriction)=@_;
1.60 matthew 636: if ($numvisible < 1) {
637: return;
638: }
639: #
640: # Set up array of selected items
1.61 matthew 641: &SetSelectedMaps($elementname);
1.60 matthew 642: #
643: # Set up the restriction call
644: if (! defined($restriction)) {
645: $restriction = sub { 1; };
646: }
647: #
648: # Build the form element
649: my $Str = "\n";
650: $Str .= '<select name="'.$elementname.'" ';
651: if ($status ne 'single') {
652: $Str .= 'multiple="true" ';
653: }
654: $Str .= 'size="'.$numvisible.'" >'."\n";
655: #
1.61 matthew 656: # Deal with 'all'
657: foreach (@SelectedMaps) {
658: if ($_ eq 'all') {
659: @SelectedMaps = ('all');
660: last;
661: }
662: }
663: #
664: # Put in option for 'all'
665: $Str .= ' <option value="all" ';
666: foreach (@SelectedMaps) {
667: if ($_ eq 'all') {
668: $Str .= 'selected ';
669: last;
670: }
671: }
672: $Str .= ">all</option>\n";
673: #
1.60 matthew 674: # Loop through the sequences
1.61 matthew 675: foreach my $seq (@Sequences) {
676: next if (! $restriction->($seq));
677: $Str .= ' <option value="'.$seq->{'symb'}.'" ';
678: foreach (@SelectedMaps) {
679: if ($seq->{'symb'} eq $_) {
1.60 matthew 680: $Str .= 'selected ';
681: last;
682: }
683: }
1.61 matthew 684: $Str .= '>'.$seq->{'title'}."</option>\n";
1.60 matthew 685: }
686: $Str .= "</select>\n";
687: return $Str;
688: }
689:
690: ##############################################
691: ##############################################
692:
693: =pod
694:
695: =item &SectionSelect($elementname,$status,$numvisible)
696:
697: Returns html for a selection box allowing the user to choose one (or more)
698: of the sections in the course.
699:
700: =over 4
701:
702: =item $elementname The name of the HTML form element
703:
704: =item $status 'multiple' or 'single' selection box
705:
706: =item $numvisible The number of options to be visible
707:
708: =item $selected Array ref to the names of the already selected sections.
709: If undef, $ENV{'form.'.$elementname} is used.
710: If $ENV{'form.'.$elementname} is also empty, none will be selected.
711:
712: =item $restriction Code reference to subroutine which returns true or
713: false. The code must expect a reference to a sequence data structure.
714:
715: =back
716:
717: =cut
718:
719: ##############################################
720: ##############################################
721: sub SectionSelect {
722: my ($elementname,$status,$numvisible)=@_;
723: if ($numvisible < 1) {
724: return;
725: }
726: #
727: # Build the form element
728: my $Str = "\n";
729: $Str .= '<select name="'.$elementname.'" ';
730: if ($status ne 'single') {
731: $Str .= 'multiple="true" ';
732: }
733: $Str .= 'size="'.$numvisible.'" >'."\n";
734: #
735: # Loop through the sequences
736: foreach my $s (@Sections) {
737: $Str .= ' <option value="'.$s.'" ';
738: foreach (@SelectedSections) {
1.61 matthew 739: if ($s eq $_) {
1.60 matthew 740: $Str .= 'selected ';
741: last;
742: }
743: }
744: $Str .= '>'.$s."</option>\n";
745: }
746: $Str .= "</select>\n";
747: return $Str;
748: }
749:
750: ##############################################
751: ##############################################
1.27 stredwic 752:
753: sub CheckFormElement {
754: my ($cache, $ENVName, $cacheName, $default)=@_;
755:
756: if(defined($ENV{'form.'.$ENVName})) {
757: $cache->{$cacheName} = $ENV{'form.'.$ENVName};
758: } elsif(!defined($cache->{$cacheName})) {
759: $cache->{$cacheName} = $default;
1.60 matthew 760: } else {
761: $ENV{'form.'.$ENVName} = $cache->{$cacheName};
1.27 stredwic 762: }
763: return;
764: }
765:
766: sub ProcessFormData{
1.29 stredwic 767: my ($cache)=@_;
1.27 stredwic 768:
1.29 stredwic 769: $cache->{'reportKey'} = 'false';
1.27 stredwic 770:
1.29 stredwic 771: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.60 matthew 772: ['download',
1.34 stredwic 773: 'reportSelected',
1.41 stredwic 774: 'StudentAssessmentStudent',
775: 'ProblemStatisticsSort']);
1.56 matthew 776: &CheckFormElement($cache, 'DownloadAll', 'DownloadAll', 'false');
777: if ($cache->{'DownloadAll'} ne 'false') {
778: # Clean the hell out of that cache!
779: # We cannot untie the hash at this scope (stupid libgd :( )
780: # So, remove every single key. What a waste of time....
781: # Of course, if you are doing this you are probably resigned
782: # to waiting a while.
783: &Apache::lonnet::logthis("Cleaning out the cache file");
784: while (my ($key,undef)=each(%$cache)) {
785: next if ($key eq 'DownloadAll');
786: delete($cache->{$key});
787: }
788: }
1.29 stredwic 789: &CheckFormElement($cache, 'Status', 'Status', 'Active');
790: &CheckFormElement($cache, 'postdata', 'reportSelected', 'Class list');
791: &CheckFormElement($cache, 'reportSelected', 'reportSelected',
792: 'Class list');
1.30 stredwic 793: $cache->{'reportSelected'} =
794: &Apache::lonnet::unescape($cache->{'reportSelected'});
1.29 stredwic 795: &CheckFormElement($cache, 'sort', 'sort', 'fullname');
796: &CheckFormElement($cache, 'download', 'download', 'false');
1.44 stredwic 797: &CheckFormElement($cache, 'StatisticsMaps',
798: 'StatisticsMaps', 'All Maps');
1.49 stredwic 799: &CheckFormElement($cache, 'StatisticsProblemSelect',
800: 'StatisticsProblemSelect', 'All Problems');
801: &CheckFormElement($cache, 'StatisticsPartSelect',
802: 'StatisticsPartSelect', 'All Parts');
1.44 stredwic 803: if(defined($ENV{'form.Section'})) {
804: my @sectionsSelected = (ref($ENV{'form.Section'}) ?
805: @{$ENV{'form.Section'}} :
806: ($ENV{'form.Section'}));
807: $cache->{'sectionsSelected'} = join(':', @sectionsSelected);
808: } elsif(!defined($cache->{'sectionsSelected'})) {
809: $cache->{'sectionsSelected'} = $cache->{'sectionList'};
810: }
1.29 stredwic 811:
1.38 stredwic 812: # student assessment
1.29 stredwic 813: if(defined($ENV{'form.CreateStudentAssessment'}) ||
814: defined($ENV{'form.NextStudent'}) ||
815: defined($ENV{'form.PreviousStudent'})) {
816: $cache->{'reportSelected'} = 'Student Assessment';
817: }
818: if(defined($ENV{'form.NextStudent'})) {
819: $cache->{'StudentAssessmentMove'} = 'next';
820: } elsif(defined($ENV{'form.PreviousStudent'})) {
821: $cache->{'StudentAssessmentMove'} = 'previous';
822: } else {
823: $cache->{'StudentAssessmentMove'} = 'selected';
824: }
825: &CheckFormElement($cache, 'StudentAssessmentStudent',
1.30 stredwic 826: 'StudentAssessmentStudent', 'All Students');
827: $cache->{'StudentAssessmentStudent'} =
828: &Apache::lonnet::unescape($cache->{'StudentAssessmentStudent'});
1.34 stredwic 829: &CheckFormElement($cache, 'DefaultColumns', 'DefaultColumns', 'false');
1.29 stredwic 830:
1.38 stredwic 831: # Problem analysis
832: &CheckFormElement($cache, 'Interval', 'Interval', '1');
833:
834: # ProblemStatistcs
835: &CheckFormElement($cache, 'DisplayCSVFormat',
836: 'DisplayFormat', 'Display Table Format');
837: &CheckFormElement($cache, 'ProblemStatisticsAscend',
838: 'ProblemStatisticsAscend', 'Ascending');
1.41 stredwic 839: &CheckFormElement($cache, 'ProblemStatisticsSort',
840: 'ProblemStatisticsSort', 'Homework Sets Order');
1.49 stredwic 841: &CheckFormElement($cache, 'DisplayLegend', 'DisplayLegend',
842: 'Hide Legend');
1.45 stredwic 843: &CheckFormElement($cache, 'SortProblems', 'SortProblems',
844: 'Sort Within Sequence');
1.38 stredwic 845:
846: # Search only form elements
1.34 stredwic 847: my @headingColumns=();
848: my @sequenceColumns=();
849: my $foundColumn = 0;
850: if(defined($ENV{'form.ReselectColumns'})) {
851: my @reselected = (ref($ENV{'form.ReselectColumns'}) ?
852: @{$ENV{'form.ReselectColumns'}}
853: : ($ENV{'form.ReselectColumns'}));
854: foreach (@reselected) {
855: if(/HeadingColumn/) {
856: push(@headingColumns, $_);
857: $foundColumn = 1;
858: } elsif(/SequenceColumn/) {
859: push(@sequenceColumns, $_);
860: $foundColumn = 1;
861: }
862: }
863: }
864:
1.37 stredwic 865: $cache->{'reportKey'} = 'false';
866: if($cache->{'reportSelected'} eq 'Analyze') {
867: $cache->{'reportKey'} = 'Analyze';
1.38 stredwic 868: } elsif($cache->{'reportSelected'} eq 'DoDiffGraph') {
869: $cache->{'reportKey'} = 'DoDiffGraph';
870: } elsif($cache->{'reportSelected'} eq 'PercentWrongGraph') {
871: $cache->{'reportKey'} = 'PercentWrongGraph';
872: }
873:
874: if(defined($ENV{'form.DoDiffGraph'})) {
875: $cache->{'reportSelected'} = 'DoDiffGraph';
876: $cache->{'reportKey'} = 'DoDiffGraph';
877: } elsif(defined($ENV{'form.PercentWrongGraph'})) {
878: $cache->{'reportSelected'} = 'PercentWrongGraph';
879: $cache->{'reportKey'} = 'PercentWrongGraph';
1.37 stredwic 880: }
881:
1.29 stredwic 882: foreach (keys(%ENV)) {
1.37 stredwic 883: if(/form\.Analyze/) {
884: $cache->{'reportSelected'} = 'Analyze';
885: $cache->{'reportKey'} = 'Analyze';
886: my $data;
887: (undef, $data)=split(':::', $_);
888: $cache->{'AnalyzeInfo'}=$data;
1.34 stredwic 889: } elsif(/form\.HeadingColumn/) {
890: my $value = $_;
891: $value =~ s/form\.//;
892: push(@headingColumns, $value);
893: $foundColumn=1;
894: } elsif(/form\.SequenceColumn/) {
895: my $value = $_;
896: $value =~ s/form\.//;
897: push(@sequenceColumns, $value);
898: $foundColumn=1;
1.27 stredwic 899: }
1.29 stredwic 900: }
1.27 stredwic 901:
1.34 stredwic 902: if($foundColumn) {
903: $cache->{'HeadingsFound'} = join(':', @headingColumns);
904: $cache->{'SequencesFound'} = join(':', @sequenceColumns);;
905: }
906: if(!defined($cache->{'HeadingsFound'}) ||
907: $cache->{'DefaultColumns'} ne 'false') {
908: $cache->{'HeadingsFound'}='HeadingColumnFull Name';
909: }
910: if(!defined($cache->{'SequencesFound'}) ||
911: $cache->{'DefaultColumns'} ne 'false') {
912: $cache->{'SequencesFound'}='All Sequences';
913: }
914: $cache->{'DefaultColumns'} = 'false';
915:
1.29 stredwic 916: return;
1.27 stredwic 917: }
918:
1.61 matthew 919: ##################################################
920: ##################################################
921:
1.27 stredwic 922: =pod
923:
924: =item &SortStudents()
925:
926: Determines which students to display and in which order. Which are
927: displayed are determined by their status(active/expired). The order
928: is determined by the sort button pressed (default to username). The
929: type of sorting is username, lastname, or section.
930:
931: =over 4
932:
933: Input: $students, $CacheData
934:
935: $students: A array pointer to a list of students (username:domain)
936:
937: $CacheData: A pointer to the hash tied to the cached data
938:
939: Output: \@order
940:
941: @order: An ordered list of students (username:domain)
942:
943: =back
944:
945: =cut
946:
947: sub SortStudents {
1.29 stredwic 948: my ($cache)=@_;
1.27 stredwic 949:
1.29 stredwic 950: my @students = split(':::',$cache->{'NamesOfStudents'});
1.27 stredwic 951: my @sorted1Students=();
1.29 stredwic 952: foreach (@students) {
953: if($cache->{'Status'} eq 'Any' ||
954: $cache->{$_.':Status'} eq $cache->{'Status'}) {
955: push(@sorted1Students, $_);
956: }
1.1 albertel 957: }
1.27 stredwic 958:
1.29 stredwic 959: my $sortBy = '';
960: if(defined($cache->{'sort'})) {
961: $sortBy = ':'.$cache->{'sort'};
1.54 matthew 962: } else {
963: $sortBy = ':fullname';
1.27 stredwic 964: }
1.54 matthew 965: my @order = sort { lc($cache->{$a.$sortBy}) cmp lc($cache->{$b.$sortBy}) ||
966: lc($cache->{$a.':fullname'}) cmp lc($cache->{$b.':fullname'}) }
1.29 stredwic 967: @sorted1Students;
1.27 stredwic 968:
969: return \@order;
970: }
971:
1.32 stredwic 972: =pod
973:
974: =item &SpaceColumns()
975:
976: Determines the width of all the columns in the chart. It is based on
977: the max of the data for that column and its header.
978:
979: =over 4
980:
981: Input: $students, $studentInformation, $headings, $ChartDB
982:
983: $students: An array pointer to a list of students (username:domain)
984:
985: $studentInformatin: The type of data for the student information. It is
986: used as part of the key in $CacheData.
987:
988: $headings: The name of the student information columns.
989:
990: $ChartDB: The name of the cache database which is opened for read/write.
991:
992: Output: None - All data stored in cache.
993:
994: =back
995:
996: =cut
997:
998: sub SpaceColumns {
999: my ($students,$studentInformation,$headings,$cache)=@_;
1000:
1001: # Initialize Lengths
1002: for(my $index=0; $index<(scalar @$headings); $index++) {
1003: my @titleLength=split(//,$headings->[$index]);
1004: $cache->{$studentInformation->[$index].':columnWidth'}=
1005: scalar @titleLength;
1006: }
1007:
1008: foreach my $name (@$students) {
1009: foreach (@$studentInformation) {
1010: my @dataLength=split(//,$cache->{$name.':'.$_});
1011: my $length=(scalar @dataLength);
1012: if($length > $cache->{$_.':columnWidth'}) {
1013: $cache->{$_.':columnWidth'}=$length;
1014: }
1015: }
1016: }
1017:
1018: return;
1019: }
1020:
1.27 stredwic 1021: sub PrepareData {
1.38 stredwic 1022: my ($c, $cacheDB, $studentInformation, $headings,$r)=@_;
1.27 stredwic 1023:
1024: # Test for access to the cache data
1025: my $courseID=$ENV{'request.course.id'};
1026: my $isRecalculate=0;
1.29 stredwic 1027: if(defined($ENV{'form.Recalculate'})) {
1.27 stredwic 1028: $isRecalculate=1;
1029: }
1030:
1.55 minaeibi 1031: my $isCached = &Apache::loncoursedata::TestCacheData($cacheDB,
1.29 stredwic 1032: $isRecalculate);
1.27 stredwic 1033: if($isCached < 0) {
1034: return "Unable to tie hash to db file.";
1035: }
1036:
1037: # Download class list information if not using cached data
1038: my %cache;
1.38 stredwic 1039: unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_WRCREAT(),0640)) {
1.29 stredwic 1040: return "Unable to tie hash to db file.";
1041: }
1042:
1.50 stredwic 1043: # if(!$isCached) {
1.27 stredwic 1044: my $processTopResourceMapReturn=
1.50 stredwic 1045: &Apache::loncoursedata::ProcessTopResourceMap(\%cache, $c);
1.27 stredwic 1046: if($processTopResourceMapReturn ne 'OK') {
1047: untie(%cache);
1048: return $processTopResourceMapReturn;
1049: }
1.50 stredwic 1050: # }
1.27 stredwic 1051:
1.29 stredwic 1052: if($c->aborted()) {
1053: untie(%cache);
1054: return 'aborted';
1055: }
1.27 stredwic 1056:
1.29 stredwic 1057: my $classlist=&Apache::loncoursedata::DownloadClasslist($courseID,
1058: $cache{'ClasslistTimestamp'},
1059: $c);
1060: foreach (keys(%$classlist)) {
1061: if(/^(con_lost|error|no_such_host)/i) {
1.27 stredwic 1062: untie(%cache);
1063: return "Error getting student data.";
1064: }
1.29 stredwic 1065: }
1.27 stredwic 1066:
1.29 stredwic 1067: if($c->aborted()) {
1068: untie(%cache);
1069: return 'aborted';
1070: }
1071:
1072: # Active is a temporary solution, remember to change
1073: Apache::loncoursedata::ProcessClasslist(\%cache,$classlist,$courseID,$c);
1074: if($c->aborted()) {
1075: untie(%cache);
1076: return 'aborted';
1077: }
1.27 stredwic 1078:
1.29 stredwic 1079: &ProcessFormData(\%cache);
1080: my $students = &SortStudents(\%cache);
1.32 stredwic 1081: &SpaceColumns($students, $studentInformation, $headings, \%cache);
1082: $cache{'updateTime:columnWidth'}=24;
1.27 stredwic 1083:
1.48 stredwic 1084: my $download = $cache{'download'};
1085: my $downloadAll = $cache{'DownloadAll'};
1086: my @allStudents=();
1087: if($download ne 'false') {
1.29 stredwic 1088: $cache{'download'} = 'false';
1.48 stredwic 1089: } elsif($downloadAll ne 'false') {
1090: $cache{'DownloadAll'} = 'false';
1091: if($downloadAll eq 'sorted') {
1092: @allStudents = @$students;
1093: } else {
1094: @allStudents = split(':::', $cache{'NamesOfStudents'});
1095: }
1096: }
1097:
1098: untie(%cache);
1099:
1100: if($download ne 'false') {
1101: my @who = ($download);
1.55 minaeibi 1102: if(&Apache::loncoursedata::DownloadStudentCourseData(\@who, 'false',
1103: $cacheDB, 'true',
1.41 stredwic 1104: 'false', $courseID,
1105: $r, $c) ne 'OK') {
1106: return 'Stop at download individual';
1107: }
1.48 stredwic 1108: } elsif($downloadAll ne 'false') {
1.55 minaeibi 1109: if(&Apache::loncoursedata::DownloadStudentCourseData(\@allStudents,
1110: 'false',
1111: $cacheDB, 'true',
1.41 stredwic 1112: 'true', $courseID,
1113: $r, $c) ne 'OK') {
1114: return 'Stop at download all';
1.27 stredwic 1115: }
1.29 stredwic 1116: }
1117:
1118: return ('OK', $students);
1.27 stredwic 1119: }
1120:
1.60 matthew 1121: sub DisplayClasslist {
1122: my ($r)=@_;
1123: #
1124: my @Fields = ('fullname','username','domain','id','section');
1125: #
1126: my $Str='';
1127: $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";
1128: $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";
1129: foreach my $field (@Fields) {
1130: $Str .= '<th><a href="/adm/statistics?sort='.$field.'">'.$field.
1131: '</a></th>';
1132: }
1133: $Str .= '</tr>'."\n";
1134: #
1135: my $alternate = 0;
1136: foreach my $student (@Students) {
1137: my $sname = $student->{'username'}.':'.$student->{'domain'};
1138: if($alternate) {
1139: $Str .= '<tr bgcolor="#ffffe6">';
1140: } else {
1141: $Str .= '<tr bgcolor="#ffffc6">';
1142: }
1143: $alternate = ($alternate + 1) % 2;
1144: #
1145: foreach my $field (@Fields) {
1146: $Str .= '<td>';
1147: if ($field eq 'fullname') {
1148: $Str .= '<a href="/adm/statistics?reportSelected=';
1149: $Str .= &Apache::lonnet::escape('Student Assessment');
1150: $Str .= '&StudentAssessmentStudent=';
1.61 matthew 1151: $Str .= &Apache::lonnet::escape($sname).'">';
1.60 matthew 1152: $Str .= $student->{$field}.' ';
1153: $Str .= '</a>';
1154: } else {
1155: $Str .= $student->{$field};
1156: }
1157: $Str .= '</td>';
1158: }
1159: $Str .= "</tr>\n";
1160: }
1161: $Str .= '</table></td></tr></table>'."\n";
1162: #
1163: $r->print($Str);
1164: $r->rflush();
1165: #
1166: return;
1167: }
1168:
1.29 stredwic 1169: sub BuildClasslist {
1.39 stredwic 1170: my ($cacheDB,$students,$studentInformation,$headings,$r)=@_;
1.29 stredwic 1171:
1172: my %cache;
1.38 stredwic 1173: unless(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
1.29 stredwic 1174: return '<html><body>Unable to tie database.</body></html>';
1.1 albertel 1175: }
1176:
1.55 minaeibi 1177: # my $Ptr = '';
1178: # $Ptr .= '<table border="0"><tbody>';
1179: # $Ptr .= '<tr><td align="right"><b>Select Sections</b>';
1180: # $Ptr .= '</td>'."\n";
1181: # $Ptr .= '<td align="left">'."\n";
1182: # my @sectionsSelected = split(':',$cache{'sectionsSelected'});
1183: # my @sections = split(':',$cache{'sectionList'});
1184: # $Ptr .= &Apache::lonhtmlcommon::MultipleSectionSelect(\@sections,
1185: # \@sectionsSelected,
1186: # 'Statistics');
1187: # $Ptr .= '</td></tr></table><br>';
1188: # $r->print($Ptr);
1189: # $r->rflush();
1190: # my %mySections = ();
1191: # foreach (@sections) { $mySections{$_} = 'True'; }
1192: # $r->print("<br>$cache{'sectionsSelected'}<br>");
1193:
1.29 stredwic 1194: my $Str='';
1195: $Str .= '<table border="0"><tr><td bgcolor="#777777">'."\n";
1196: $Str .= '<table border="0" cellpadding="3"><tr bgcolor="#e6ffff">'."\n";
1197:
1198: my $displayString = '<td align="left"><a href="/adm/statistics?';
1199: $displayString .= 'sort=LINKDATA">DISPLAYDATA </a></td>'."\n";
1.55 minaeibi 1200: $Str .= &Apache::lonhtmlcommon::CreateHeadings(\%cache,
1.39 stredwic 1201: $studentInformation,
1.32 stredwic 1202: $headings, $displayString);
1.29 stredwic 1203: $Str .= '</tr>'."\n";
1.39 stredwic 1204:
1.29 stredwic 1205: my $alternate=0;
1206: foreach (@$students) {
1.55 minaeibi 1207: # if ($mySections{$cache{$_.':'.'section'}} ne 'True') {next;}
1.29 stredwic 1208: my ($username, $domain) = split(':', $_);
1209: if($alternate) {
1.32 stredwic 1210: $Str .= '<tr bgcolor="#ffffe6">';
1.29 stredwic 1211: } else {
1.32 stredwic 1212: $Str .= '<tr bgcolor="#ffffc6">';
1.29 stredwic 1213: }
1214: $alternate = ($alternate + 1) % 2;
1215: foreach my $data (@$studentInformation) {
1.32 stredwic 1216: $Str .= '<td>';
1.29 stredwic 1217: if($data eq 'fullname') {
1218: $Str .= '<a href="/adm/statistics?reportSelected=';
1.30 stredwic 1219: $Str .= &Apache::lonnet::escape('Student Assessment');
1220: $Str .= '&StudentAssessmentStudent=';
1221: $Str .= &Apache::lonnet::escape($cache{$_.':'.$data}).'">';
1.32 stredwic 1222: $Str .= $cache{$_.':'.$data}.' ';
1.29 stredwic 1223: $Str .= '</a>';
1.32 stredwic 1224: } elsif($data eq 'updateTime') {
1225: $Str .= '<a href="/adm/statistics?reportSelected=';
1226: $Str .= &Apache::lonnet::escape('Class list');
1227: $Str .= '&download='.$_.'">';
1228: $Str .= $cache{$_.':'.$data}.' ';
1229: $Str .= ' </a>';
1230: } else {
1231: $Str .= $cache{$_.':'.$data}.' ';
1.29 stredwic 1232: }
1233:
1.32 stredwic 1234: $Str .= '</td>'."\n";
1.29 stredwic 1235: }
1.1 albertel 1236: }
1.29 stredwic 1237:
1.32 stredwic 1238: $Str .= '</tr>'."\n";
1.29 stredwic 1239: $Str .= '</table></td></tr></table>'."\n";
1.39 stredwic 1240: $r->print($Str);
1241: $r->rflush();
1.29 stredwic 1242:
1.27 stredwic 1243: untie(%cache);
1.1 albertel 1244:
1.39 stredwic 1245: return;
1.1 albertel 1246: }
1247:
1.33 stredwic 1248: sub CreateMainMenu {
1249: my ($status, $reports)=@_;
1250:
1251: my $Str = '';
1252:
1253: $Str .= '<table border="0"><tbody><tr>'."\n";
1.63 ! matthew 1254: $Str .= '<td></td>'."\n";
1.57 minaeibi 1255: $Str .= '<td align="center"><b>Select a Report</b></td>'."\n";
1256: $Str .= '<td align="center"><b>Student Status</b></td></tr>'."\n";
1.33 stredwic 1257: $Str .= '<tr>'."\n";
1258: $Str .= '<td align="center"><input type="submit" name="Refresh" ';
1.63 ! matthew 1259: $Str .= 'value="Update Display" /></td>'."\n";
1.33 stredwic 1260: $Str .= '<td align="center">';
1261: $Str .= '<select name="reportSelected" onchange="document.';
1262: $Str .= 'Statistics.submit()">'."\n";
1263:
1264: foreach (sort(keys(%$reports))) {
1265: next if($_ eq 'reportSelected');
1266: $Str .= '<option name="'.$_.'"';
1267: if($reports->{'reportSelected'} eq $reports->{$_}) {
1268: $Str .= ' selected=""';
1269: }
1270: $Str .= '>'.$reports->{$_}.'</option>'."\n";
1271: }
1272: $Str .= '</select></td>'."\n";
1273:
1274: $Str .= '<td align="center">';
1275: $Str .= &Apache::lonhtmlcommon::StatusOptions($status, 'Statistics');
1276: $Str .= '</td>'."\n";
1277:
1278: $Str .= '</tr></tbody></table>'."\n";
1279: $Str .= '<hr>'."\n";
1280:
1281: return $Str;
1282: }
1283:
1.29 stredwic 1284: sub BuildStatistics {
1285: my ($r)=@_;
1286:
1287: my $c = $r->connection;
1.32 stredwic 1288: my @studentInformation=('fullname','section','id','domain','username',
1289: 'updateTime');
1290: my @headings=('Full Name', 'Section', 'PID', 'Domain', 'User Name',
1291: 'Last Updated');
1.55 minaeibi 1292: my $spacing = ' ';
1.52 minaeibi 1293:
1.29 stredwic 1294: my %reports = ('classlist' => 'Class list',
1295: 'problem_statistics' => 'Problem Statistics',
1296: 'student_assessment' => 'Student Assessment',
1.58 minaeibi 1297: 'percentage' => 'Correct-problems Plot',
1.40 minaeibi 1298: # 'activitylog' => 'Activity Log',
1.29 stredwic 1299: 'reportSelected' => 'Class list');
1.27 stredwic 1300:
1301: my %cache;
1.29 stredwic 1302: my $courseID=$ENV{'request.course.id'};
1303: my $cacheDB = "/home/httpd/perl/tmp/$ENV{'user.name'}".
1304: "_$ENV{'user.domain'}_$courseID\_statistics.db";
1305:
1.47 www 1306: $r->print(&Apache::lonhtmlcommon::Title('Course Statistics and Charts'));
1.41 stredwic 1307:
1.55 minaeibi 1308: my ($returnValue, $students) = &PrepareData($c, $cacheDB,
1309: \@studentInformation,
1.38 stredwic 1310: \@headings,$r);
1.29 stredwic 1311: if($returnValue ne 'OK') {
1.41 stredwic 1312: $r->print($returnValue."\n".'</body></html>');
1.29 stredwic 1313: return OK;
1314: }
1.41 stredwic 1315: if(!$c->aborted()) {
1.55 minaeibi 1316: &Apache::loncoursedata::CheckForResidualDownload($cacheDB,
1.41 stredwic 1317: 'true', 'true',
1318: $courseID,
1319: $r, $c);
1320: }
1.29 stredwic 1321:
1322: my $GoToPage;
1.38 stredwic 1323: if(tie(%cache,'GDBM_File',$cacheDB,&GDBM_READER(),0640)) {
1.29 stredwic 1324: $GoToPage = $cache{'reportSelected'};
1325: $reports{'reportSelected'} = $cache{'reportSelected'};
1.55 minaeibi 1326: if(defined($cache{'reportKey'}) &&
1327: !exists($reports{$cache{'reportKey'}}) &&
1.37 stredwic 1328: $cache{'reportKey'} ne 'false') {
1329: $reports{$cache{'reportKey'}} = $cache{'reportSelected'};
1330: }
1.29 stredwic 1331:
1332: if(defined($cache{'OptionResponses'})) {
1.46 stredwic 1333: $reports{'problem_analysis'} = 'Option Response Analysis';
1.29 stredwic 1334: }
1335:
1336: $r->print('<form name="Statistics" ');
1337: $r->print('method="post" action="/adm/statistics">');
1.33 stredwic 1338: $r->print(&CreateMainMenu($cache{'Status'}, \%reports));
1.39 stredwic 1339: $r->rflush();
1.29 stredwic 1340: untie(%cache);
1341: } else {
1.27 stredwic 1342: $r->print('<html><body>Unable to tie database.</body></html>');
1.29 stredwic 1343: return OK;
1344: }
1345:
1346: if($GoToPage eq 'Activity Log') {
1.30 stredwic 1347: &Apache::lonproblemstatistics::Activity();
1.29 stredwic 1348: } elsif($GoToPage eq 'Problem Statistics') {
1.55 minaeibi 1349: &Apache::lonproblemstatistics::BuildProblemStatisticsPage($cacheDB,
1350: $students,
1351: $courseID,
1.36 minaeibi 1352: $c,$r);
1.46 stredwic 1353: } elsif($GoToPage eq 'Option Response Analysis') {
1.39 stredwic 1354: &Apache::lonproblemanalysis::BuildProblemAnalysisPage($cacheDB, $r);
1.29 stredwic 1355: } elsif($GoToPage eq 'Student Assessment') {
1.62 matthew 1356: &Apache::lonstudentassessment::BuildStudentAssessmentPage($r, $c);
1.29 stredwic 1357: } elsif($GoToPage eq 'Analyze') {
1.55 minaeibi 1358: &Apache::lonproblemanalysis::BuildAnalyzePage($cacheDB, $students,
1.39 stredwic 1359: $courseID, $r);
1.40 minaeibi 1360: } elsif($GoToPage eq 'DoDiffGraph' || $GoToPage eq 'PercentWrongGraph') {
1.43 stredwic 1361: my $courseDescription = $ENV{'course.'.$courseID.'.description'};
1362: $courseDescription =~ s/\ /"_"/eg;
1363: &Apache::lonproblemstatistics::BuildGraphicChart($GoToPage, $cacheDB,
1364: $courseDescription,
1.45 stredwic 1365: $students, $courseID,
1366: $r, $c);
1.29 stredwic 1367: } elsif($GoToPage eq 'Class list') {
1.60 matthew 1368: &DisplayClasslist($r);
1369: # &BuildClasslist($cacheDB, $students, \@studentInformation,
1370: # \@headings, $r);
1.58 minaeibi 1371: } elsif($GoToPage eq 'Correct-problems Plot') {
1.49 stredwic 1372: &Apache::lonpercentage::BuildPercentageGraph($cacheDB, $students,
1373: $courseID, $c, $r);
1.27 stredwic 1374: }
1375:
1376: $r->print('</form>'."\n");
1.29 stredwic 1377: $r->print("\n".'</body>'."\n".'</html>');
1378: $r->rflush();
1.27 stredwic 1379:
1.29 stredwic 1380: return OK;
1.27 stredwic 1381: }
1.1 albertel 1382:
1383: # ================================================================ Main Handler
1384:
1385: sub handler {
1.31 minaeibi 1386: my $r=shift;
1.34 stredwic 1387:
1388: # $jr = $r;
1.51 www 1389:
1390: my $loaderror=&Apache::lonnet::overloaderror($r);
1391: if ($loaderror) { return $loaderror; }
1392: $loaderror=
1393: &Apache::lonnet::overloaderror($r,
1394: $ENV{'course.'.$ENV{'request.course.id'}.'.home'});
1395: if ($loaderror) { return $loaderror; }
1.1 albertel 1396:
1.27 stredwic 1397: unless(&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) {
1398: $ENV{'user.error.msg'}=
1399: $r->uri.":vgr:0:0:Cannot view grades for complete course";
1.55 minaeibi 1400: return HTTP_NOT_ACCEPTABLE;
1.27 stredwic 1401: }
1402:
1403: # Set document type for header only
1404: if($r->header_only) {
1405: if ($ENV{'browser.mathml'}) {
1406: $r->content_type('text/xml');
1407: } else {
1408: $r->content_type('text/html');
1409: }
1410: &Apache::loncommon::no_cache($r);
1411: $r->send_http_header;
1412: return OK;
1413: }
1414:
1415: unless($ENV{'request.course.fn'}) {
1.1 albertel 1416: my $requrl=$r->uri;
1.27 stredwic 1417: $ENV{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";
1.55 minaeibi 1418: return HTTP_NOT_ACCEPTABLE;
1.27 stredwic 1419: }
1.1 albertel 1420:
1.27 stredwic 1421: $r->content_type('text/html');
1422: $r->send_http_header;
1.1 albertel 1423:
1.60 matthew 1424: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
1.61 matthew 1425: ['sort',
1426: 'StudentAssessmentStudent']);
1.60 matthew 1427:
1.59 matthew 1428: &PrepareClasslist($r);
1.60 matthew 1429:
1430: &PrepareCourseData($r);
1.59 matthew 1431:
1.29 stredwic 1432: &BuildStatistics($r);
1.27 stredwic 1433:
1434: return OK;
1.1 albertel 1435: }
1436: 1;
1.59 matthew 1437:
1438: =pod
1439:
1440: =back
1441:
1442: =cut
1443:
1.1 albertel 1444: __END__
1.31 minaeibi 1445:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>