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