Diff for /loncom/interface/spreadsheet/studentcalc.pm between versions 1.8 and 1.28

version 1.8, 2003/05/29 13:39:38 version 1.28, 2005/03/03 17:52:36
Line 45  studentcalc Line 45  studentcalc
 ###################################################  ###################################################
 package Apache::studentcalc;  package Apache::studentcalc;
   
   use warnings FATAL=>'all';
   no warnings 'uninitialized';
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::lonnet;  use Apache::lonnet;
Line 54  use Apache::lonnavmaps; Line 57  use Apache::lonnavmaps;
 use Apache::Spreadsheet();  use Apache::Spreadsheet();
 use Apache::assesscalc();  use Apache::assesscalc();
 use HTML::Entities();  use HTML::Entities();
 use Spreadsheet::WriteExcel;  
 use Time::HiRes;  use Time::HiRes;
   use Apache::lonlocal;
   
 @Apache::studentcalc::ISA = ('Apache::Spreadsheet');  @Apache::studentcalc::ISA = ('Apache::Spreadsheet');
   
 my @Sequences = ();  my @Sequences = ();
   my $navmap;
 my %Exportrows = ();  my %Exportrows = ();
   
 my $current_course;  my $current_course;
   
 sub initialize {  sub initialize {
     &initialize_sequence_cache();      &initialize_sequence_cache();
       &Apache::assesscalc::initialize($navmap);
 }  }
   
 sub initialize_package {  sub initialize_package {
Line 85  sub ensure_correct_sequence_data { Line 90  sub ensure_correct_sequence_data {
 sub initialize_sequence_cache {  sub initialize_sequence_cache {
     #      #
     # Set up the sequences and assessments      # Set up the sequences and assessments
     @Sequences = ();      undef(@Sequences);
     my ($top,$sequences,$assessments) =       undef($navmap);
         &Apache::loncoursedata::get_sequence_assessment_data();      $navmap = Apache::lonnavmaps::navmap->new();
     if (! defined($top) || ! ref($top)) {      if (!defined($navmap)) {
         # There has been an error, better report it          &Apache::lonnet::logthis('student spreadsheet:Can not open Coursemap');
         &Apache::lonnet::logthis('top is undefined (studentcalc.pm)');      }
         return;      my @all_sequences = $navmap->retrieveResources(undef,
                                                  sub { shift->is_map(); },1,0,1);
       for my $sequence ($navmap->getById('0.0'), @all_sequences) {
    if ($navmap->hasResource($sequence,sub { shift->is_problem(); }, 0)){
               push(@Sequences,$sequence);
           }
     }      }
     @Sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');  }
   
   sub get_resources {
       my ($seq) = @_;
       return () if (! defined($navmap) || ! ref($navmap));
       my @resources = $navmap->retrieveResources($seq,
                                                  sub { shift->is_problem(); },
                                                  0,0,0);
       return @resources;
 }  }
   
 sub clear_package {  sub clear_package {
     @Sequences = undef;      undef(@Sequences);
     %Exportrows = undef;      undef(%Exportrows);
       &Apache::assesscalc::clear_package();
 }  }
   
 sub get_title {  sub get_title {
Line 106  sub get_title { Line 125  sub get_title {
     my @title = ();      my @title = ();
     #      #
     # Determine the students name      # Determine the students name
     my %userenv = &Apache::loncoursedata::GetUserName($self->{'name'},      my $name = &Apache::loncommon::plainname($self->{'name'},
                                                       $self->{'domain'});       $self->{'domain'});
     my $name = join(' ',  
                  @userenv{'firstname','middlename','lastname','generation'});  
     $name =~ s/\s+$//;  
   
     push (@title,$name);      push (@title,$name);
     push (@title,$self->{'coursedesc'});      push (@title,$self->{'coursedesc'});
     push (@title,scalar(localtime(time)));      push (@title,&Apache::lonlocal::locallocaltime(time));
     return @title;      return @title;
 }  }
   
Line 124  sub get_html_title { Line 139  sub get_html_title {
     my $title = '<h1>'.$name;      my $title = '<h1>'.$name;
     if ($ENV{'user.name'} ne $self->{'name'} &&       if ($ENV{'user.name'} ne $self->{'name'} && 
         $ENV{'user.domain'} ne $self->{'domain'}) {          $ENV{'user.domain'} ne $self->{'domain'}) {
         $title .= &Apache::loncommon::aboutmewrapper          $title .= ' '.&Apache::loncommon::aboutmewrapper
                                     ($self->{'name'}.'@'.$self->{'domain'},                                      ($self->{'name'}.'@'.$self->{'domain'},
                                      $self->{'name'},$self->{'domain'});                                       $self->{'name'},$self->{'domain'});
     }      }
Line 136  sub get_html_title { Line 151  sub get_html_title {
   
 sub parent_link {  sub parent_link {
     my $self = shift;      my $self = shift;
     my $link .= '<p><a href="/adm/classcalc?'.      return '<p><a href="/adm/classcalc">'.&mt('Course level sheet').'</a></p>'."\n";
         'sname='.$self->{'name'}.  }
             '&sdomain='.$self->{'domain'}.'">'.  
                 'Course level sheet</a></p>'."\n";  sub convenience_links {
     return $link;      my $self = shift;
       my ($resource) = @_;
       my $result=&Apache::loncommon::submlink('<img src="/adm/lonMisc/subm_button.gif" border="0" />',$self->{'name'},$self->{'domain'},$resource->symb,'LONcatInfo');
       $result .= &Apache::loncommon::pgrdlink('<img src="/adm/lonMisc/pgrd_button.gif" border="0" />',$self->{'name'},$self->{'domain'},$resource->symb,'LONcatInfo');
       $result .= &Apache::loncommon::pprmlink('<img src="/adm/lonMisc/pprm_button.gif" border="0" />',$self->{'name'},$self->{'domain'},$resource->symb,'LONcatInfo');
       return $result;
 }  }
   
 sub outsheet_html {  sub outsheet_html {
     my $self = shift;      my $self = shift;
     my ($r) = @_;      my ($r) = @_;
       my $importcolor = '#FFFFAA';
       my $exportcolor = '#88FF88';
     ####################################      ####################################
     # Get the list of assessment files #      # Get the list of assessment files #
     ####################################      ####################################
Line 153  sub outsheet_html { Line 175  sub outsheet_html {
     my $editing_is_allowed = &Apache::lonnet::allowed('mgr',      my $editing_is_allowed = &Apache::lonnet::allowed('mgr',
                                                 $ENV{'request.course.id'});                                                  $ENV{'request.course.id'});
     ####################################      ####################################
       # Report any calculation errors    #
       ####################################
       $r->print($self->html_report_error());
       ####################################
     # Determine table structure        #      # Determine table structure        #
     ####################################      ####################################
     my $num_uneditable = 26;      my $num_uneditable = 26;
     my $num_left = 52-$num_uneditable;      my $num_left = 52-$num_uneditable;
       my %lt=&Apache::lonlocal::texthash(
          'st' => 'Student',
          'im' => 'Import',
          'ca' => 'Calculations',
          'as' => 'Assessment',
          'ro' => 'Row',
          );
     my $tableheader =<<"END";      my $tableheader =<<"END";
 <p>  <p>
 <table border="2">  <table border="2">
 <tr>  <tr>
   <th colspan="2" rowspan="2"><font size="+2">Student</font></th>    <th colspan="2" rowspan="2"><font size="+2">$lt{'st'}</font></th>
   <td bgcolor="#FFDDDD" colspan="$num_uneditable">    <td bgcolor="$importcolor" colspan="$num_uneditable">
       <b><font size="+1">Import</font></b></td>        <b><font size="+1">$lt{'im'}</font></b></td>
   <td colspan="$num_left">    <td colspan="$num_left">
       <b><font size="+1">Calculations</font></b></td>        <b><font size="+1">$lt{'ca'}</font></b></td>
 </tr><tr>  </tr><tr>
 END  END
     my $label_num = 0;      my $label_num = 0;
     foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){      foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){
         if ($label_num<$num_uneditable) {           if ($label_num<$num_uneditable) { 
             $tableheader .='<td bgcolor="#FFDDDD">';              $tableheader .='<td bgcolor="'.$importcolor.'">';
         } else {          } else {
             $tableheader .='<td>';              $tableheader .='<td>';
         }          }
Line 181  END Line 214  END
     $tableheader .="</tr>\n";      $tableheader .="</tr>\n";
     if ($self->blackout()) {      if ($self->blackout()) {
         $r->print('<font color="red" size="+2"><p>'.          $r->print('<font color="red" size="+2"><p>'.
                   'Some computations are not available at this time.<br />'.                    &mt('Some computations are not available at this time.').'<br />'.
                   'There are problems whose status you are allowed to view.'.                    &mt('There are problems whose status you are not allowed to view.').
                   '</font></p>'."\n");                    '</font></p>'."\n");
     } else {      } else {
         $r->print($tableheader);          $r->print($tableheader);
Line 190  END Line 223  END
         # Print out template row          # Print out template row
         if (exists($ENV{'request.role.adv'}) && $ENV{'request.role.adv'}) {          if (exists($ENV{'request.role.adv'}) && $ENV{'request.role.adv'}) {
             $r->print('<tr><td>Template</td><td>&nbsp;</td>'.              $r->print('<tr><td>Template</td><td>&nbsp;</td>'.
                       $self->html_template_row($num_uneditable)."</tr>\n");                        $self->html_template_row($num_uneditable,
                                                  $importcolor)."</tr>\n");
         }          }
         #          #
         # Print out summary/export row          # Print out summary/export row
         $r->print('<tr><td>Summary</td><td>0</td>'.          $r->print('<tr><td>'.&mt('Summary').'</td><td>0</td>'.
                   $self->html_export_row()."</tr>\n");                    $self->html_export_row($exportcolor)."</tr>\n");
     }      }
     $r->print("</table>\n");      $r->print("</table>\n");
     #      #
Line 204  END Line 238  END
         $tableheader =<<"END";          $tableheader =<<"END";
 </p><p>  </p><p>
 <table border="2">  <table border="2">
 <tr><th>Row</th><th>Assessment</th>  <tr><th>$lt{'ro'}</th><th>&nbsp;</th><th>$lt{'as'}</th>
 END  END
     } else {      } else {
         $tableheader =<<"END";          $tableheader =<<"END";
 </p><p>  </p><p>
 <table border="2">  <table border="2">
 <tr><th>&nbsp;</th><th>Assessment</th>  <tr><th>&nbsp;</th><th>$lt{'as'}</th>
 END  END
     }      }
     foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){      foreach (split(//,'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')){
Line 228  END Line 262  END
         &initialize_sequence_cache();          &initialize_sequence_cache();
     }      }
     foreach my $Sequence (@Sequences) {      foreach my $Sequence (@Sequences) {
  next if ($Sequence->{'num_assess'} < 1);   $r->print("<h3>".$Sequence->compTitle."</h3>\n");
  $r->print("<h3>".$Sequence->{'title'}."</h3>\n");  
   $r->print($tableheader);    $r->print($tableheader);
  foreach my $resource (@{$Sequence->{'contents'}}) {   foreach my $resource (&get_resources($Sequence)) {
     next if ($resource->{'type'} ne 'assessment');      my $rownum = $self->get_row_number_from_key($resource->symb);
     my $rownum = $self->get_row_number_from_key($resource->{'symb'});  
             my $assess_filename = $self->{'row_source'}->{$rownum};              my $assess_filename = $self->{'row_source'}->{$rownum};
             my $row_output = '<tr>';              my $row_output = '<tr>';
             if ($editing_is_allowed) {              if ($editing_is_allowed) {
                 $row_output .= '<td>'.$rownum.'</td>';                  $row_output .= '<td>'.$rownum.'</td>';
                   $row_output .= '<td>'.$self->convenience_links($resource).'</td>';
                 $row_output .= '<td>'.                  $row_output .= '<td>'.
                     '<a href="/adm/assesscalc?sname='.$self->{'name'}.                      '<a href="/adm/assesscalc?sname='.$self->{'name'}.
                     '&sdomain='.$self->{'domain'}.                      '&sdomain='.$self->{'domain'}.
                     '&filename='.$assess_filename.                      '&filename='.$assess_filename.
                     '&usymb='.&Apache::lonnet::escape($resource->{'symb'}).                      '&usymb='.&Apache::lonnet::escape($resource->symb).
                     '">'.$resource->{'title'}.'</a><br />';                      '">'.$resource->compTitle.'</a><br />';
                 $row_output .= &assess_file_selector($rownum,                  $row_output .= &assess_file_selector($rownum,
                                                      $assess_filename,                                                       $assess_filename,
                                                      \@AssessFileNames).                                                       \@AssessFileNames).
                                                          '</td>';                                                           '</td>';
             } else {              } else {
                 $row_output .= '<td><a href="'.$resource->{'src'}.'?symb='.                  $row_output .= '<td><a href="'.$resource->src.'?symb='.
                     &Apache::lonnet::escape($resource->{'symb'}).                      &Apache::lonnet::escape($resource->symb).
                     '">Go&nbsp;To</a>';                      '">Go&nbsp;To</a>';
                 $row_output .= '</td><td>'.$resource->{'title'}.'</td>';                  $row_output .= '</td><td>'.$resource->compTitle.'</td>';
             }              }
             if ($self->blackout() && $self->{'blackout_rows'}->{$rownum}>0) {              if ($self->blackout() && $self->{'blackout_rows'}->{$rownum}>0) {
                 $row_output .=                   $row_output .= 
                     '<td colspan="52">Unavailable at this time</td></tr>'."\n";                      '<td colspan="52">'.&mt('Unavailable at this time').'</td></tr>'."\n";
             } else {              } else {
                 $row_output .= $self->html_row($num_uneditable,$rownum).                  $row_output .= $self->html_row($num_uneditable,$rownum,
                                                  $exportcolor,$importcolor).
                     "</tr>\n";                      "</tr>\n";
             }              }
             $r->print($row_output);              $r->print($row_output);
Line 328  sub csv_rows { Line 362  sub csv_rows {
     # writes the meat of the spreadsheet to an excel worksheet.  Called      # writes the meat of the spreadsheet to an excel worksheet.  Called
     # by Spreadsheet::outsheet_excel;      # by Spreadsheet::outsheet_excel;
     my $self = shift;      my $self = shift;
     my ($filehandle) = @_;      my ($connection,$filehandle) = @_;
     #      #
     # Write a header row      # Write a header row
     $self->csv_output_row($filehandle,undef,      $self->csv_output_row($filehandle,undef,
                           ('Container','Assessment title'));                            (&mt('Sequence or Folder'),&mt('Assessment title')));
     #      #
     # Write each assessments row      # Write each assessments row
     if (scalar(@Sequences)< 1) {      if (scalar(@Sequences)< 1) {
         &initialize_sequence_cache();          &initialize_sequence_cache();
     }      }
     foreach my $Sequence (@Sequences) {      foreach my $Sequence (@Sequences) {
  next if ($Sequence->{'num_assess'} < 1);   foreach my $resource (&get_resources($Sequence)) {
  foreach my $resource (@{$Sequence->{'contents'}}) {      my $rownum = $self->get_row_number_from_key($resource->symb);
     my $rownum = $self->get_row_number_from_key($resource->{'symb'});              my @assessdata = ($Sequence->compTitle,
             my @assessdata = ($Sequence->{'title'},                                $resource->compTitle);
                               $resource->{'title'});  
             $self->csv_output_row($filehandle,$rownum,@assessdata);              $self->csv_output_row($filehandle,$rownum,@assessdata);
         }          }
     }      }
Line 354  sub excel_rows { Line 387  sub excel_rows {
     # writes the meat of the spreadsheet to an excel worksheet.  Called      # writes the meat of the spreadsheet to an excel worksheet.  Called
     # by Spreadsheet::outsheet_excel;      # by Spreadsheet::outsheet_excel;
     my $self = shift;      my $self = shift;
     my ($worksheet,$cols_output,$rows_output) = @_;      my ($connection,$worksheet,$cols_output,$rows_output) = @_;
     #      #
     # Write a header row      # Write a header row
     $cols_output = 0;      $cols_output = 0;
     foreach my $value ('Container','Assessment title') {      foreach my $value ('Container','Assessment title') {
         $worksheet->write($rows_output,$cols_output++,$value);          $worksheet->write($rows_output,$cols_output++,&mt($value));
     }      }
     $rows_output++;          $rows_output++;    
     #      #
Line 368  sub excel_rows { Line 401  sub excel_rows {
         &initialize_sequence_cache();          &initialize_sequence_cache();
     }      }
     foreach my $Sequence (@Sequences) {      foreach my $Sequence (@Sequences) {
  next if ($Sequence->{'num_assess'} < 1);   foreach my $resource (&get_resources($Sequence)) {
  foreach my $resource (@{$Sequence->{'contents'}}) {      my $rownum = $self->get_row_number_from_key($resource->symb);
     my $rownum = $self->get_row_number_from_key($resource->{'symb'});              my @assessdata = ($Sequence->compTitle,
             my @assessdata = ($Sequence->{'title'},                                $resource->compTitle);
                               $resource->{'title'});  
             $self->excel_output_row($worksheet,$rownum,$rows_output++,              $self->excel_output_row($worksheet,$rownum,$rows_output++,
                                     @assessdata);                                      @assessdata);
         }          }
Line 385  sub outsheet_recursive_excel { Line 417  sub outsheet_recursive_excel {
     my ($r) = @_;      my ($r) = @_;
 }   } 
   
 sub set_row_sources {  ##
     my $self = shift;  ## Routines to deal with sequences in the safe space
     while (my ($cell,$value) = each(%{$self->{'formulas'}})) {  ##
         next if ($cell !~ /^A(\d+)/ && $1 > 0);  sub get_rows_in_sequence {
         my $row = $1;      my $self = shift();
         (undef,$value) = split('__&&&__',$value);      my ($sequence) = @_;
         $value = 'Default' if (! defined($value));      my @Rows;
         $self->{'row_source'}->{$row} = $value;      my @resources = &get_resources($sequence);
       foreach my $resource (@resources) {
           my $rownum = $self->get_row_number_from_key($resource->symb);
           push (@Rows,$rownum);
       }
       return @Rows;
   }
   
   sub remove_sequence_data_from_safe_space {
       my $self = shift();
       my $command = 'undef(%Sequence_Rows);';
       $self->{'safe'}->reval($command);
   }
   
   sub put_sequence_data_in_safe_space {
       my $self = shift();
       my $data = 'undef(%Sequence_Rows);';
       # Build up the %Sequence_Rows hash - each sequence title is associated with
       # an array pointer, which holds the rows in the sequence.
       foreach my $seq (@Sequences) {
           my @Rows = $self->get_rows_in_sequence($seq);
           # 
           # Potential problems with sequence titles:
           # 1. duplicate titles - they get the total for the titles
           # 2. control characters in titles - use q{} around the string to
           #    deal with it.  
           my $title = &HTML::Entities::decode($seq->{'title'});
           $title =~ s/&\#058;/:/g;
           if (@Rows) {
               $data .= 'push(@{$Sequence_Rows{"'.quotemeta($title).'"}},'.
                   '('.join(',',@Rows).'));'."\n";;
           }
     }      }
       my $new_code = $data.<<'END';
   sub SUMSEQ {
       my ($col,@titles) = @_;
       return 'bad column: '.$col if ($col !~ /^[A-z]$/);
       my $sum = 0;
       foreach my $title (@titles) {
           while (my ($seq_title,$rows) = each(%Sequence_Rows)) {
               my $regexp;
               if ($title =~ /^regexp:(.*)$/) {
                   $regexp = $1;
               } elsif (lc($title) eq 'all') {
                   $regexp = '.';
               }
               if (defined($regexp)) {
                   next if ($seq_title !~ /$regexp/);
               } else {
                   next if ($seq_title ne $title);
               }
               foreach my $rownum (@{$rows}) {
                   my $cell = $col.$rownum;
                   if (exists($sheet_values{$cell})) {
                       $sum += $sheet_values{$cell};
                   }
               }
           }
       }
       return $sum;
   }
   END
       $self->{'safe'}->reval($new_code);
     return;      return;
 }  }
   
   ##
   ## Main computation method
   ##
 sub compute {  sub compute {
     my $self = shift;      my $self = shift;
     $self->logthis('computing');      my ($r) = @_;
       my $connection = $r->connection();
       if ($connection->aborted()) { $self->cleanup; return; }
     if (! defined($current_course) ||      if (! defined($current_course) ||
         $current_course ne $ENV{'request.course.id'}) {          $current_course ne $ENV{'request.course.id'} ||
           ! @Sequences ) {
         $current_course = $ENV{'request.course.id'};          $current_course = $ENV{'request.course.id'};
         &clear_package();          &clear_package();
         &initialize_sequence_cache();          &initialize_sequence_cache();
     }      }
     $self->initialize_safe_space();      $self->initialize_safe_space();
     my @sequences = @Sequences;      &Apache::assesscalc::initialize_package($self->{'name'},$self->{'domain'},
     if (@sequences < 1) {                                              $navmap);
         my ($top,$sequences,$assessments) =   
             &Apache::loncoursedata::get_sequence_assessment_data();  
         if (! defined($top) || ! ref($top)) {  
             &Apache::lonnet::logthis('top is undefined');  
             return;  
         }  
         @sequences = @{$sequences} if (ref($sequences) eq 'ARRAY');  
     }  
     &Apache::assesscalc::initialize_package($self->{'name'},$self->{'domain'});  
     my %f = $self->formulas();      my %f = $self->formulas();
     #      #
     # Process the formulas list -       # Process the formulas list - 
     #   the formula for the A column of a row is symb__&&__filename      #   the formula for the A column of a row is symb__&&__filename
     my %c = $self->constants();      my %c = $self->constants();
     foreach my $seq (@sequences) {      foreach my $seq (@Sequences) {
         next if ($seq->{'num_assess'}<1);          foreach my $resource (&get_resources($seq)) {
         foreach my $resource (@{$seq->{'contents'}}) {              if ($connection->aborted()) { $self->cleanup(); return; }
             next if ($resource->{'type'} ne 'assessment');              my $rownum = $self->get_row_number_from_key($resource->symb);
             my $rownum = $self->get_row_number_from_key($resource->{'symb'});  
             my $cell = 'A'.$rownum;              my $cell = 'A'.$rownum;
             my $assess_filename = 'Default';              my $assess_filename = 'Default';
             if (exists($self->{'row_source'}->{$rownum})) {              if (exists($self->{'row_source'}->{$rownum})) {
Line 435  sub compute { Line 524  sub compute {
             } else {              } else {
                 $self->{'row_source'}->{$rownum} = $assess_filename;                  $self->{'row_source'}->{$rownum} = $assess_filename;
             }              }
             $f{$cell} = $resource->{'symb'}.'__&&&__'.$assess_filename;              $f{$cell} = $resource->symb.'__&&&__'.$assess_filename;
             my $assessSheet = Apache::assesscalc->new($self->{'name'},              if ($connection->aborted()) { $self->cleanup(); return; }
                                                       $self->{'domain'},              my $assessSheet;
                                                       $assess_filename,                  $assessSheet = Apache::assesscalc->new($self->{'name'},
                                                       $resource->{'symb'});                                                         $self->{'domain'},
             my @exportdata = $assessSheet->export_data();                                                         $assess_filename,
                                                          $resource->symb);
               my @exportdata = $assessSheet->export_data($r);
               #
               if ($assessSheet->badcalc()) {
                   $self->set_calcerror(
               &mt('Error computing row for assessment "[_1]" (row [_2]):[_3]',
                   $assessSheet->get_title(),$rownum,$assessSheet->calcerror()));
               }
               #
               if ($connection->aborted()) { $self->cleanup(); return; }
             if ($assessSheet->blackout()) {              if ($assessSheet->blackout()) {
                 $self->blackout(1);                  $self->blackout(1);
                 $self->{'blackout_rows'}->{$rownum} = 1;                  $self->{'blackout_rows'}->{$rownum} = 1;
Line 465  sub compute { Line 564  sub compute {
     }      }
     $self->constants(\%c);      $self->constants(\%c);
     $self->formulas(\%f);      $self->formulas(\%f);
       $self->put_sequence_data_in_safe_space();
     $self->calcsheet();      $self->calcsheet();
       $self->remove_sequence_data_from_safe_space();
     #      #
     # Store export row in cache      # Store export row in cache
     my @exportarray=$self->exportrow();      my @exportarray=$self->exportrow();
Line 474  sub compute { Line 575  sub compute {
     $Exportrows{$student}->{'data'} = \@exportarray;      $Exportrows{$student}->{'data'} = \@exportarray;
     # save export row      # save export row
     $self->save_export_data();      $self->save_export_data();
       #
       $self->save() if ($self->need_to_save());
       return;
   }
   
   sub set_row_sources {
       my $self = shift;
       while (my ($cell,$value) = each(%{$self->{'formulas'}})) {
           next if ($cell !~ /^A(\d+)$/ || $1 < 1);
           my $row = $1;
           (undef,$value) = split('__&&&__',$value);
           $value = 'Default' if (! defined($value));
           $self->{'row_source'}->{$row} = $value;
       }
     return;      return;
 }  }
   
Line 485  sub set_row_numbers { Line 600  sub set_row_numbers {
         next if ($row == 0);          next if ($row == 0);
         my ($symb,undef) = split('__&&&__',$formula);          my ($symb,undef) = split('__&&&__',$formula);
         $self->{'row_numbers'}->{$symb} = $row;          $self->{'row_numbers'}->{$symb} = $row;
           $self->{'maxrow'} = $row if ($row > $self->{'maxrow'});
     }      }
 }  }
   
Line 514  These rows are saved in the courses dire Line 630  These rows are saved in the courses dire
 #############################################  #############################################
 #############################################  #############################################
 sub load_cached_export_rows {  sub load_cached_export_rows {
     %Exportrows = undef;      undef(%Exportrows);
     my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets',      my @tmp = &Apache::lonnet::dump('nohist_calculatedsheets',
      $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},       $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
      $ENV{'course.'.$ENV{'request.course.id'}.'.num'},undef);       $ENV{'course.'.$ENV{'request.course.id'}.'.num'},undef);
Line 553  Writes the export data for this student Line 669  Writes the export data for this student
 #############################################  #############################################
 sub save_export_data {  sub save_export_data {
     my $self = shift;      my $self = shift;
     return if ($self->temporary());  
     my $student = $self->{'name'}.':'.$self->{'domain'};      my $student = $self->{'name'}.':'.$self->{'domain'};
       return if ($self->temporary());
       if ($self->badcalc()){
           # do not save data away when calculations have not been done properly.
           delete($Exportrows{$student});
           return;
       }
     return if (! exists($Exportrows{$student}));      return if (! exists($Exportrows{$student}));
       &Apache::assesscalc::save_cached_export_rows($self->{'name'},
                                                    $self->{'domain'});
     return if (! $self->is_default());      return if (! $self->is_default());
     my $key = join(':',($self->{'name'},$self->{'domain'},'studentcalc')).':';      my $key = join(':',($self->{'name'},$self->{'domain'},'studentcalc')).':';
     my $timekey = $key.'.time';      my $timekey = $key.'.time';
     my $newstore = join('___;___',      my $newstore = join('___;___',
                         @{$Exportrows{$student}->{'data'}});                          @{$Exportrows{$student}->{'data'}});
     $newstore = '___=___'.$newstore;      $newstore = '___=___'.$newstore;
     &Apache::lonnet::put('nohist_calculatedsheets',      my $result= &Apache::lonnet::put('nohist_calculatedsheets',
                          { $key     => $newstore,                           { $key     => $newstore,
                            $timekey => $Exportrows{$student}->{'time'} },                             $timekey => $Exportrows{$student}->{'time'} },
                          $self->{'cdom'},                           $self->{'cdom'},
Line 586  spreadsheet only if necessary. Line 709  spreadsheet only if necessary.
 #############################################  #############################################
 sub export_data {  sub export_data {
     my $self = shift;      my $self = shift;
       my ($r) = @_;
       my $connection = $r->connection();
     my $student = $self->{'name'}.':'.$self->{'domain'};      my $student = $self->{'name'}.':'.$self->{'domain'};
     if (! exists($Exportrows{$student}) ||      if (! exists($Exportrows{$student}) ||
           ! defined($Exportrows{$student}) ||
           ! exists($Exportrows{$student}->{'data'}) ||
           ! defined($Exportrows{$student}->{'data'}) ||
           ! exists($Exportrows{$student}->{'time'}) ||
           ! defined($Exportrows{$student}->{'time'}) ||
         ! $self->check_expiration_time($Exportrows{$student}->{'time'})) {          ! $self->check_expiration_time($Exportrows{$student}->{'time'})) {
         $self->compute();          $self->compute($r);
     }      }
     my @Data = @{$Exportrows{$student}->{'data'}};      if ($connection->aborted()) { $self->cleanup(); return; }
     for (my $i=0; $i<=$#Data;$i++) {      my @Data;
         $Data[$i]="'".$Data[$i]."'" if ($Data[$i]=~/\D/ && defined($Data[$i]));      if ($self->badcalc()) {
           @Data = ();
       } else {
           @Data = @{$Exportrows{$student}->{'data'}};
           for (my $i=0; $i<=$#Data;$i++) {
               if ($Data[$i]=~/\D/ && defined($Data[$i])) {
                   $Data[$i]="'".$Data[$i]."'";
               }
           }
     }      }
     return @Data;      return @Data;
 }  }

Removed from v.1.8  
changed lines
  Added in v.1.28


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