Diff for /loncom/interface/statistics/lonstathelpers.pm between versions 1.36 and 1.51

version 1.36, 2005/02/01 15:15:28 version 1.51, 2005/11/12 03:58:55
Line 49  routines that are needed across multiple Line 49  routines that are needed across multiple
 package Apache::lonstathelpers;  package Apache::lonstathelpers;
   
 use strict;  use strict;
 use Apache::lonnet();  use Apache::lonnet;
 use Apache::loncommon();  use Apache::loncommon();
 use Apache::lonhtmlcommon();  use Apache::lonhtmlcommon();
 use Apache::loncoursedata();  use Apache::loncoursedata();
Line 68  use Storable qw(freeze thaw); Line 68  use Storable qw(freeze thaw);
   
 =item &render_resource($resource)  =item &render_resource($resource)
   
 Input: a resource generated from   Input: a navmaps resource
 &Apache::loncoursedata::get_sequence_assessment_data().  
   
 Retunrs: a scalar containing html for a rendering of the problem  Retunrs: a scalar containing html for a rendering of the problem
 within a table.  within a table.
Line 82  sub render_resource { Line 81  sub render_resource {
     my ($resource) = @_;      my ($resource) = @_;
     ##      ##
     ## Render the problem      ## Render the problem
     my $base;      my ($base) = ($resource->src =~ m|^(.*/)[^/]*$|);
     ($base,undef) = ($resource->{'src'} =~ m|(.*/)[^/]*$|);      $base="http://".$ENV{'SERVER_NAME'}.$base;
     $base = "http://".$ENV{'SERVER_NAME'}.$base;      my ($src,$symb)=($resource->src,&Apache::lonnet::escape($resource->symb));
     my $rendered_problem =       my $rendered_problem = &Apache::lonnet::ssi_body($src.'?symb='.$symb);
         &Apache::lonnet::ssi_body($resource->{'src'}.'?symb='.&Apache::lonnet::escape($resource->{'symb'}));  
     $rendered_problem =~ s/<\s*form\s*/<nop /g;      $rendered_problem =~ s/<\s*form\s*/<nop /g;
     $rendered_problem =~ s|(<\s*/form\s*>)|<\/nop>|g;      $rendered_problem =~ s|(<\s*/form\s*>)|<\/nop>|g;
     return '<table bgcolor="ffffff"><tr><td>'.      return '<table bgcolor="ffffff"><tr><td>'.
Line 100  sub render_resource { Line 98  sub render_resource {
   
 =pod  =pod
   
 =item &ProblemSelector($AcceptedResponseTypes)  =item &get_resources
   
   =cut
   
   ####################################################
   ####################################################
   sub get_resources {
       my ($navmap,$sequence) = @_;
       my @resources = $navmap->retrieveResources($sequence,
                                                  sub { shift->is_problem(); },
                                                  0,0,0);
       return @resources;
   }
   
   ####################################################
   ####################################################
   
   =pod
   
   =item &problem_selector($AcceptedResponseTypes)
   
 Input: scalar containing regular expression which matches response  Input: scalar containing regular expression which matches response
 types to show.  '.' will yield all, '(option|radiobutton)' will match  types to show.  '.' will yield all, '(option|radiobutton)' will match
Line 114  Skips 'survey' problems. Line 131  Skips 'survey' problems.
   
 ####################################################  ####################################################
 ####################################################  ####################################################
 sub ProblemSelector {  sub problem_selector {
     my ($AcceptedResponseTypes) = @_;      my ($AcceptedResponseTypes,$sequence_addendum) = @_;
     my $Str;      my $Str;
     $Str = "\n<table>\n";      $Str = "\n<table>\n";
     my $rb_count =0;      my $rb_count =0;
     foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess('all')) {      my ($navmap,@sequences) = 
         next if ($seq->{'num_assess'}<1);          &Apache::lonstatistics::selected_sequences_with_assessments('all');
       return $navmap if (! ref($navmap)); # error
       foreach my $seq (@sequences) {
         my $seq_str = '';          my $seq_str = '';
         foreach my $res (@{$seq->{'contents'}}) {          foreach my $res (&get_resources($navmap,$seq)) {
             next if ($res->{'type'} ne 'assessment');              foreach my $part (@{$res->parts}) {
             foreach my $part (@{$res->{'parts'}}) {                  my @response_ids   = $res->responseIds($part);
                 my $partdata = $res->{'partdata'}->{$part};                  my @response_types = $res->responseType($part);
                 for (my $i=0;$i<scalar(@{$partdata->{'ResponseTypes'}});$i++){                  for (my $i=0;$i<scalar(@response_types);$i++){
                     my $respid = $partdata->{'ResponseIds'}->[$i];                      my $respid = $response_ids[$i];
                     my $resptype = $partdata->{'ResponseTypes'}->[$i];                      my $resptype = $response_types[$i];
                     if ($resptype =~ m/$AcceptedResponseTypes/) {                      if ($resptype =~ m/$AcceptedResponseTypes/) {
                         my $value = &make_target_id({symb=>$res->{'symb'},                          my $value = &make_target_id({symb=>$res->symb,
                                                      part=>$part,                                                       part=>$part,
                                                      respid=>$respid,                                                       respid=>$respid,
                                                      resptype=>$resptype});                                                       resptype=>$resptype});
                         my $checked = '';                          my $checked = '';
                         if ($ENV{'form.problemchoice'} eq $value) {                          if ($env{'form.problemchoice'} eq $value) {
                             $checked = 'checked ';                              $checked = 'checked ';
                         }                          }
                         my $title = $res->{'title'};                          my $title = $res->compTitle;
                         if (! defined($title) || $title eq '') {                          if (! defined($title) || $title eq '') {
                             ($title) = ($res->{'src'} =~ m:/([^/]*)$:);                              ($title) = ($res->src =~ m:/([^/]*)$:);
                         }                          }
                         $seq_str .= '<tr>'.                          $seq_str .= '<tr>'.
                             qq{<td><input type="radio" id="$rb_count" name="problemchoice" value="$value" $checked /></td>}.                              qq{<td><input type="radio" id="$rb_count" name="problemchoice" value="$value" $checked /></td>}.
                             '<td><label for="'.$rb_count.'">'.$resptype.'</label></td>'.                              '<td><label for="'.$rb_count.'">'.$resptype.'</label></td>'.
                             '<td><label for="'.$rb_count.'">'.$title.'</label>';                              '<td><label for="'.$rb_count.'">'.$title.'</label>';
                         if (scalar(@{$partdata->{'ResponseIds'}}) > 1) {                          if (scalar(@response_ids) > 1) {
                             $seq_str .= &mt('response').' '.$respid;                              $seq_str .= &mt('response').' '.$respid;
                         }                          }
                         my $link = $res->{'src'}.'?symb='.                          my $link = $res->src.'?symb='.
                             &Apache::lonnet::escape($res->{'symb'});                              &Apache::lonnet::escape($res->symb);
                         $seq_str .= ('&nbsp;'x2).                          $seq_str .= ('&nbsp;'x2).
                             qq{<a target="preview" href="$link">view</a>};                              qq{<a target="preview" href="$link">view</a>};
                         $seq_str .= "</td></tr>\n";                          $seq_str .= "</td></tr>\n";
Line 160  sub ProblemSelector { Line 179  sub ProblemSelector {
             }              }
         }          }
         if ($seq_str ne '') {          if ($seq_str ne '') {
             $Str .= '<tr><td>&nbsp</td><td colspan="2"><b>'.$seq->{'title'}.'</b></td>'.              $Str .= '<tr><td>&nbsp</td>'.
                   '<td colspan="2"><b>'.$seq->compTitle.'</b></td>'.
                 "</tr>\n".$seq_str;                  "</tr>\n".$seq_str;
               if (defined($sequence_addendum)) {
                   $Str .= '<tr>'.
                       ('<td>&nbsp</td>'x2).
                       '<td align="right">'.$sequence_addendum.'</td>'.
                       "</tr>\n";
               }
         }          }
     }      }
     $Str .= "</table>\n";      $Str .= "</table>\n";
Line 195  and their contents.  A checkbox is provi Line 221  and their contents.  A checkbox is provi
 ####################################################  ####################################################
 sub MultipleProblemSelector {  sub MultipleProblemSelector {
     my ($navmap,$inputname,$formname)=@_;      my ($navmap,$inputname,$formname)=@_;
     my $cid = $ENV{'request.course.id'};      my $cid = $env{'request.course.id'};
     my $Str;      my $Str;
     # Massage the input as needed.      # Massage the input as needed.
     if (! defined($navmap)) {      if (! defined($navmap)) {
Line 236  END Line 262  END
     my $iterator = $navmap->getIterator(undef, undef, undef, 1);      my $iterator = $navmap->getIterator(undef, undef, undef, 1);
     my $sequence_string;      my $sequence_string;
     my $seq_id = 0;      my $seq_id = 0;
     my @Accumulator = (&new_accumulator($ENV{'course.'.$cid.'.description'},      my @Accumulator = (&new_accumulator($env{'course.'.$cid.'.description'},
                                         '',                                          '',
                                         '',                                          '',
                                         $seq_id++,                                          $seq_id++,
Line 301  sub new_accumulator { Line 327  sub new_accumulator {
                     '&nbsp;'.$res->compTitle.'</label>'.                      '&nbsp;'.$res->compTitle.'</label>'.
                     ('&nbsp;'x2).'<a target="preview" '.                      ('&nbsp;'x2).'<a target="preview" '.
                     'href="'.$res->src.'?symb='.                      'href="'.$res->src.'?symb='.
                          &Apache::lonnet::escape($res->{'symb'}).'">view</a>'.                           &Apache::lonnet::escape($res->symb).'">view</a>'.
                     '</td></tr>'.$/;                      '</td></tr>'.$/;
             } else {               } else { 
                 if (defined($target)) {                  if (defined($target)) {
Line 319  sub new_accumulator { Line 345  sub new_accumulator {
 sub get_selected_symbs {  sub get_selected_symbs {
     my ($inputfield) = @_;      my ($inputfield) = @_;
     my $field = 'form.'.$inputfield;      my $field = 'form.'.$inputfield;
     my @Symbs;      my @symbs = (map {
     if (exists($ENV{$field})) {                       &Apache::lonnet::unescape($_);
         if (! ref($ENV{$field})) {                       } &Apache::loncommon::get_env_multiple($field));
             @Symbs = (&Apache::lonnet::unescape($ENV{$field}));      return @symbs;
         } else {  
             @Symbs = (map {&Apache::lonnet::unescape($_);} @{$ENV{$field}});  
         }  
     }  
     return @Symbs;  
 }  }
   
 ####################################################  ####################################################
Line 433  sub get_prev_curr_next { Line 454  sub get_prev_curr_next {
     #      #
     # Build an array with the data we need to search through      # Build an array with the data we need to search through
     my @Resource;      my @Resource;
     foreach my $seq (&Apache::lonstatistics::Sequences_with_Assess('all')) {      my ($navmap,@sequences) = 
         foreach my $res (@{$seq->{'contents'}}) {          &Apache::lonstatistics::selected_sequences_with_assessments('all');
             next if ($res->{'type'} ne 'assessment');      return $navmap if (! ref($navmap));
             foreach my $part (@{$res->{'parts'}}) {      foreach my $seq (@sequences) {
                 my $partdata = $res->{'partdata'}->{$part};          my @resources = &get_resources($navmap,$seq);
                 if ($partdata->{'Survey'} && ($granularity eq 'part_survey')){          foreach my $res (@resources) {
               foreach my $part (@{$res->parts}) {
                   if ($res->is_survey($part) && ($granularity eq 'part_survey')){
                     push (@Resource,                      push (@Resource,
                           { symb     => $res->{symb},                            { symb     => $res->symb,
                             part     => $part,                              part     => $part,
                             resource => $res,                              resource => $res,
                         } );                          } );
                 } elsif ($granularity eq 'part') {                  } elsif ($granularity eq 'part') {
                     push (@Resource,                      push (@Resource,
                           { symb     => $res->{symb},                            { symb     => $res->symb,
                             part     => $part,                              part     => $part,
                             resource => $res,                              resource => $res,
                         } );                          } );
                 } elsif ($granularity eq 'response') {                  } elsif ($granularity eq 'response') {
                       my @response_ids   = $res->responseIds($part);
                       my @response_types = $res->responseType($part);
                     for (my $i=0;                      for (my $i=0;
                          $i<scalar(@{$partdata->{'ResponseTypes'}});                           $i<scalar(@response_ids);
                          $i++){                           $i++){
                         my $respid = $partdata->{'ResponseIds'}->[$i];                          my $respid   = $response_ids[$i];
                         my $resptype = $partdata->{'ResponseTypes'}->[$i];                          my $resptype = $response_types[$i];
                         next if ($resptype !~ m/$AcceptableResponseTypes/);                          next if ($resptype !~ m/$AcceptableResponseTypes/);
                         push (@Resource,                          push (@Resource,
                               { symb     => $res->{symb},                                { symb     => $res->symb,
                                 part     => $part,                                  part     => $part,
                                 respid   => $partdata->{'ResponseIds'}->[$i],                                  respid   => $respid,
                                   resptype => $resptype,
                                 resource => $res,                                  resource => $res,
                                 resptype => $resptype  
                                 } );                                  } );
                     }                      }
                 }                  }
Line 520  sub get_prev_curr_next { Line 545  sub get_prev_curr_next {
         $curr = $Resource[$curr_idx  ];          $curr = $Resource[$curr_idx  ];
         $next = $Resource[$curr_idx+1];          $next = $Resource[$curr_idx+1];
     }      }
     return ($prev,$curr,$next);      return ($navmap,$prev,$curr,$next);
 }  }
   
   
Line 621  sub analyze_problem_as_student { Line 646  sub analyze_problem_as_student {
     my $symb = $resource->{'symb'};      my $symb = $resource->{'symb'};
     my $analysis = &get_from_analysis_cache($sname,$sdom,$symb);      my $analysis = &get_from_analysis_cache($sname,$sdom,$symb);
     if (! defined($analysis)) {      if (! defined($analysis)) {
         my $courseid = $ENV{'request.course.id'};          my $courseid = $env{'request.course.id'};
         my $Answ=&Apache::lonnet::ssi($url,('grade_target' => 'analyze',          my $Answ=&Apache::lonnet::ssi($url,('grade_target' => 'analyze',
                                             'grade_domain' => $sdom,                                              'grade_domain' => $sdom,
                                             'grade_username' => $sname,                                              'grade_username' => $sname,
Line 845  prior to every analysis lookup. Line 870  prior to every analysis lookup.
 #####################################################  #####################################################
 sub ensure_proper_cache {  sub ensure_proper_cache {
     my ($symb) = @_;      my ($symb) = @_;
     my $cid = $ENV{'request.course.id'};      my $cid = $env{'request.course.id'};
     my $new_filename =  '/home/httpd/perl/tmp/'.      my $new_filename =  '/home/httpd/perl/tmp/'.
         'problemanalysis_'.$cid.'_analysis_cache.db';          'problemanalysis_'.$cid.'_analysis_cache.db';
     if (! defined($cache_filename) ||      if (! defined($cache_filename) ||
Line 1110  sub get_problem_data { Line 1135  sub get_problem_data {
                 }                  }
             }              }
             # End of logging code              # End of logging code
             next if ($key !~ /^$part/);              next if ($key !~ /^\Q$part\E/);
             $key =~ s/^$part\.//;              $key =~ s/^\Q$part\E\.//;
             if (ref($value) eq 'ARRAY') {              if (ref($value) eq 'ARRAY') {
                 if ($key eq 'options') {                  if ($key eq 'options') {
                     $Partdata{$part}->{'_Options'}=$value;                      $Partdata{$part}->{'_Options'}=$value;
Line 1234  sub limit_by_time_form { Line 1259  sub limit_by_time_form {
     }       } 
     $timecheckbox .= 'OnChange="javascript:toggle_limitby_activity(this.checked);" ';      $timecheckbox .= 'OnChange="javascript:toggle_limitby_activity(this.checked);" ';
     $timecheckbox .= ' />';      $timecheckbox .= ' />';
     $Str .= '<legend>'.&mt('[_1] Limit by time',$timecheckbox).'</legend>';      $Str .= '<legend><label>'.&mt('[_1] Limit by time',$timecheckbox).'</label></legend>';
     $Str .= &mt('Start Time: [_1]',$startdateform).'<br />';      $Str .= &mt('Start Time: [_1]',$startdateform).'<br />';
     $Str .= &mt('&nbsp;End Time: [_1]',$enddateform).'<br />';      $Str .= &mt('&nbsp;End Time: [_1]',$enddateform).'<br />';
     $Str .= '</fieldset>';      $Str .= '</fieldset>';
Line 1242  sub limit_by_time_form { Line 1267  sub limit_by_time_form {
 }  }
   
 sub limit_by_time {  sub limit_by_time {
     if (exists($ENV{'form.limit_by_time'}) &&      if (exists($env{'form.limit_by_time'}) &&
         $ENV{'form.limit_by_time'} ne '' ) {          $env{'form.limit_by_time'} ne '' ) {
         return 1;          return 1;
     } else {      } else {
         return 0;          return 0;
Line 1258  sub get_time_limits { Line 1283  sub get_time_limits {
     return ($starttime,$endtime);      return ($starttime,$endtime);
 }  }
   
   
   
 ####################################################  
 ####################################################  
   
 =pod  
   
 =item sections_description   
   
 Inputs: @Sections, an array of sections  
   
 Returns: A text description of the sections selected.  
   
 =cut  
   
 ####################################################  
 ####################################################  
 sub sections_description {  
     my @Sections = @_;  
     my $sectionstring = '';  
     if (scalar(@Sections) > 1) {  
         if (scalar(@Sections) > 2) {  
             my $last = pop(@Sections);  
             $sectionstring = "Sections ".join(', ',@Sections).', and '.$last;  
         } else {  
             $sectionstring = "Sections ".join(' and ',@Sections);  
         }  
     } else {  
         if ($Sections[0] eq 'all') {  
             $sectionstring = "All sections";  
         } else {  
             $sectionstring = "Section ".$Sections[0];  
         }  
     }  
     return $sectionstring;  
 }  
   
 ####################################################  ####################################################
 ####################################################  ####################################################
   
Line 1317  sub manage_caches { Line 1305  sub manage_caches {
         join(',',          join(',',
              map {               map {
                      &Apache::lonnet::escape($_);                       &Apache::lonnet::escape($_);
                  } sort(@Apache::lonstatistics::SelectedSections)                   } sort(&Apache::lonstatistics::get_selected_sections())
              );               );
     my $statuskey = $Apache::lonstatistics::enrollment_status;      my $statuskey = $Apache::lonstatistics::enrollment_status;
     if (exists($ENV{'form.ClearCache'}) ||       if (exists($env{'form.ClearCache'}) || 
         exists($ENV{'form.updatecaches'}) ||           exists($env{'form.updatecaches'}) || 
         (exists($ENV{'form.firstrun'}) && $ENV{'form.firstrun'} ne 'no') ||          (exists($env{'form.firstrun'}) && $env{'form.firstrun'} ne 'no') ||
         (exists($ENV{'form.prevsection'}) &&          (exists($env{'form.prevsection'}) &&
             $ENV{'form.prevsection'} ne $sectionkey) ||              $env{'form.prevsection'} ne $sectionkey) ||
         (exists($ENV{'form.prevenrollstatus'}) &&          (exists($env{'form.prevenrollstatus'}) &&
             $ENV{'form.prevenrollstatus'} ne $statuskey)              $env{'form.prevenrollstatus'} ne $statuskey)
         ) {          ) {
         if (defined($update_message)) {          if (defined($update_message)) {
             $r->print($update_message);              $r->print($update_message);
         }          }
           if (0) {
               &Apache::lonnet::logthis('Updating mysql student data caches');
           }
         &gather_full_student_data($r,$formname,$inputname);          &gather_full_student_data($r,$formname,$inputname);
     }      }
     #      #
Line 1344  sub manage_caches { Line 1335  sub manage_caches {
          '<input type="hidden" name="prevenrollstatus" value="'.$statuskey.'" />'           '<input type="hidden" name="prevenrollstatus" value="'.$statuskey.'" />'
          );           );
     #      #
     if (! exists($ENV{'form.firstrun'})) {      if (! exists($env{'form.firstrun'})) {
         $r->print('<input type="hidden" name="firstrun" value="yes" />');          $r->print('<input type="hidden" name="firstrun" value="yes" />');
     } else {      } else {
         $r->print('<input type="hidden" name="firstrun" value="no" />');          $r->print('<input type="hidden" name="firstrun" value="no" />');
Line 1354  sub manage_caches { Line 1345  sub manage_caches {
 }  }
   
 sub gather_full_student_data {  sub gather_full_student_data {
     &Apache::lonnet::logthis('called gather_full_student_data');  
     my ($r,$formname,$inputname) = @_;      my ($r,$formname,$inputname) = @_;
     my $status_type;      my $status_type;
     if (defined($formname)) {      if (defined($formname)) {
Line 1378  sub gather_full_student_data { Line 1368  sub gather_full_student_data {
         return if ($c->aborted());          return if ($c->aborted());
         my $status = &Apache::loncoursedata::ensure_current_full_data          my $status = &Apache::loncoursedata::ensure_current_full_data
             ($student->{'username'},$student->{'domain'},              ($student->{'username'},$student->{'domain'},
              $ENV{'request.course.id'});               $env{'request.course.id'});
         &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,          &Apache::lonhtmlcommon::Increment_PrgWin($r,\%prog_state,
                                                  &mt('last student'));                                                   &mt('last student'));
     }      }
Line 1387  sub gather_full_student_data { Line 1377  sub gather_full_student_data {
     return;      return;
 }  }
   
   ####################################################
   ####################################################
   
   =pod
   
   =item &submission_report_form
   
   Input: The originating reportSelected value for the current stats page.
   
   Output: Scalar containing HTML with needed form elements and a link to 
   the student submission reports page.
   
   =cut
   
   ####################################################
   ####################################################
   sub submission_report_form {
       my ($original_report) = @_;
       # Note: In the link below we change the reportSelected value.  If
       # the user hits the 'back' button on the browser after getting their
       # student submissions report, this value may still be around.  So we
       # output a script block to set it properly.  If the $original_report
       # value is unset, you are just asking for trouble.
       if (! defined($original_report)) {
           &Apache::lonnet::logthis
               ('someone called lonstathelpers::submission_report_form without '.
                ' enough input.');
       }
       my $html = $/.
           '<script type="Text/JavaScript">'.
           "document.Statistics.reportSelected.value='$original_report';".
           '</script>'.
           '<input type="hidden" name="correctans" value="true" />'.
           '<input type="hidden" name="prob_status" value="true" />'.
           '<input type="hidden" name="all_sub" value="true" />';
       my $output_selector = $/.'<select name="output">'.$/;
       foreach ('HTML','Excel','CSV') {
           $output_selector .= '    <option value="'.lc($_).'"';
           if ($env{'form.output'} eq lc($_)) {
               $output_selector .= ' selected ';
           }
           $output_selector .='>'.&mt($_).'</option>'.$/;
       } 
       $output_selector .= '</select>'.$/;
       my $link = '<a href="javascript:'.
          q{document.Statistics.reportSelected.value='student_submission_reports';}.
          'document.Statistics.submit();">';
       $html.= &mt('View data as [_1] [_2]go[_3]',$output_selector,
                   $link,'</a>').$/;
       return $html
   }
   
 ####################################################  ####################################################
 ####################################################  ####################################################

Removed from v.1.36  
changed lines
  Added in v.1.51


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>