Diff for /loncom/interface/spreadsheet/assesscalc.pm between versions 1.43 and 1.58

version 1.43, 2005/05/15 02:28:23 version 1.58, 2007/01/23 01:36:26
Line 174  sub initialize { Line 174  sub initialize {
 ########################################################  ########################################################
 ########################################################  ########################################################
 sub initialize_package {  sub initialize_package {
     my ($sname,$sdomain,$in_navmap) = @_;      my ($sname,$sdomain,$in_navmap,$calling_sheet) = @_;
     $current_name   = $sname;      $current_name   = $sname;
     $current_domain = $sdomain;      $current_domain = $sdomain;
     $navmap = $in_navmap;      $navmap = $in_navmap;
Line 185  sub initialize_package { Line 185  sub initialize_package {
         undef(%courseopt);          undef(%courseopt);
     }      }
     &load_cached_export_rows();      &load_cached_export_rows();
     &load_parameter_caches();      &load_parameter_caches($calling_sheet);
     &Apache::loncoursedata::clear_internal_caches();      &Apache::loncoursedata::clear_internal_caches();
 }  }
   
Line 202  sub initialize_package { Line 202  sub initialize_package {
 ########################################################  ########################################################
 ########################################################  ########################################################
 sub load_parameter_caches {  sub load_parameter_caches {
       my ($calling_sheet) = @_;
     my $userprefix = $current_name.':'.$current_domain.'_';      my $userprefix = $current_name.':'.$current_domain.'_';
     $userprefix =~ s/:/_/g;      $userprefix =~ s/:/_/g;
     #      #
Line 234  sub load_parameter_caches { Line 235  sub load_parameter_caches {
     if (! %userdata) {      if (! %userdata) {
         %userdata = &Apache::loncoursedata::get_current_state($current_name,          %userdata = &Apache::loncoursedata::get_current_state($current_name,
                                                               $current_domain);                                                                $current_domain);
    my ($tmp) = %userdata;
    if ($tmp =~ /^error:(.*)/) {
       $calling_sheet->set_calcerror($1);
    }
         $userdata{'loadtime'} = time;          $userdata{'loadtime'} = time;
     }      }
     return;      return;
Line 272  sub ensure_current_caches { Line 277  sub ensure_current_caches {
         undef(%useropt);          undef(%useropt);
         undef(%userdata);          undef(%userdata);
     }      }
     &load_parameter_caches();      &load_parameter_caches($self);
 }  }
   
 ##################################################  ##################################################
Line 290  Returns: The value of a parameter, or '' Line 295  Returns: The value of a parameter, or ''
   
 This function cascades through the possible levels searching for a value for  This function cascades through the possible levels searching for a value for
 a parameter.  The levels are checked in the following order:  a parameter.  The levels are checked in the following order:
 user, course (at section level and course level), map, and lonnet::metadata.  user, course (at group, section level and course level), map, and 
   lonnet::metadata.
 This function uses %parmhash, which must be tied prior to calling it.  This function uses %parmhash, which must be tied prior to calling it.
 This function also requires %courseopt and %useropt to be initialized for  This function also requires %courseopt and %useropt to be initialized for
 this user and course.  this user and course.
Line 301  this user and course. Line 307  this user and course.
 ##################################################  ##################################################
 sub parmval {  sub parmval {
     my $self = shift;      my $self = shift;
     my ($what,$symb,$uname,$udom,$csec,$recurse)=@_;      my ($what,$symb,$uname,$udom,$csec,$recurse,$mapname,$id,$fn,$groups)=@_;
     $uname = $self->{'name'}    if (! defined($uname));      $uname  = $self->{'name'}     if (! defined($uname));
     $udom  = $self->{'domain'}  if (! defined($udom));      $udom   = $self->{'domain'}   if (! defined($udom));
     $csec  = $self->{'section'} if (! defined($csec));      $csec   = $self->{'section'}  if (! defined($csec));
     $symb  = $self->{'symb'}    if (! defined($symb));      $groups = $self->{'groups'}   if (! defined($groups)); 
       $symb   = $self->{'symb'}     if (! defined($symb));
     #      #
     my $result='';      my $result='';
     #      #
     # This should be a       # This should be a 
     my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);      if (!defined($mapname) || !defined($id) || !defined($fn)) {
    ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);
    $mapname = &Apache::lonnet::deversion($mapname);
       }
     # Cascading lookup scheme      # Cascading lookup scheme
     my $rwhat=$what;      my $rwhat=$what;
     $what =~ s/^parameter\_//;      $what =~ s/^parameter\_//;
Line 332  sub parmval { Line 342  sub parmval {
     my $ucourselevel  = $usercourseprefix.'.'.$what;      my $ucourselevel  = $usercourseprefix.'.'.$what;
     my $ucourselevelr = $usercourseprefix.'.'.$symbparm;      my $ucourselevelr = $usercourseprefix.'.'.$symbparm;
     my $ucourselevelm = $usercourseprefix.'.'.$mapparm;      my $ucourselevelm = $usercourseprefix.'.'.$mapparm;
    # check user      # check user
     if (defined($uname)) {      if (defined($uname)) {
         return $useropt{$ucourselevelr} if (defined($useropt{$ucourselevelr}));          return $useropt{$ucourselevelr} if (defined($useropt{$ucourselevelr}));
         return $useropt{$ucourselevelm} if (defined($useropt{$ucourselevelm}));          return $useropt{$ucourselevelm} if (defined($useropt{$ucourselevelm}));
         return $useropt{$ucourselevel}  if (defined($useropt{$ucourselevel}));          return $useropt{$ucourselevel}  if (defined($useropt{$ucourselevel}));
     }      }
       # check groups
       if (defined($groups) && ref($groups) eq 'ARRAY') {
           foreach my $group (@{$groups}) {
               foreach my $level ($symbparm,$mapparm,$what) {
                   my $item = $courseprefix.'.['.$group.'].'.$level;
                   if (defined($courseopt{$item})) {
                       return $courseopt{$item};
                   }
               }
           }
       }
     # check section      # check section
     if (defined($csec)) {      if (defined($csec)) {
         return $courseopt{$seclevelr} if (defined($courseopt{$seclevelr}));          return $courseopt{$seclevelr} if (defined($courseopt{$seclevelr}));
Line 367  sub parmval { Line 388  sub parmval {
  if ($part eq '') { $part='0'; }   if ($part eq '') { $part='0'; }
  my $newwhat=$rwhat;   my $newwhat=$rwhat;
  $newwhat=~s/\Q$space\E/$part/;   $newwhat=~s/\Q$space\E/$part/;
  my $partgeneral=$self->parmval($newwhat,$symb,$uname,$udom,$csec,1);   my $partgeneral=$self->parmval($newwhat,$symb,$uname,$udom,$csec,1,
          $mapname,$id,$fn,$groups);
  if (defined($partgeneral)) { return $partgeneral; }   if (defined($partgeneral)) { return $partgeneral; }
     }      }
     if ($recurse) { return undef; }      if ($recurse) { return undef; }
Line 512  sub assess_html_row { Line 534  sub assess_html_row {
     my @rowdata = $self->get_row($row);      my @rowdata = $self->get_row($row);
     my $num_cols_output = 0;      my $num_cols_output = 0;
     my $row_html;      my $row_html;
     if (exists($nice_parameter_name{$parameter_name})) {      my $name=$self->get_parm_name($parameter_name);
         my $name = $nice_parameter_name{$parameter_name};      if ($name ne '') {
         $name =~ s/ /\ /g;          $name =~ s/ /\ /g;
         $row_html .= '<td>'.$name.'<br />'.$parameter_name.'</td>';          $row_html .= '<td>'.$name.'<br />'.$parameter_name.'</td>';
     } else {      } else {
Line 525  sub assess_html_row { Line 547  sub assess_html_row {
             $row_html .= &Apache::Spreadsheet::html_uneditable_cell($cell,              $row_html .= &Apache::Spreadsheet::html_uneditable_cell($cell,
                                                                     '#FFDDDD');                                                                      '#FFDDDD');
         } else {          } else {
             $row_html .= '<td bgcolor="#EOFFDD">';              $row_html .= '<td bgcolor="#E0FFDD">';
             $row_html .= &Apache::Spreadsheet::html_editable_cell($cell,              $row_html .= &Apache::Spreadsheet::html_editable_cell($cell,
                                                                   '#E0FFDD',1);                                                                    '#E0FFDD',1);
         }          }
Line 548  sub csv_rows { Line 570  sub csv_rows {
     # Write each row      # Write each row
     foreach my $rownum (sort {$a <=> $b} ($self->rows())) {      foreach my $rownum (sort {$a <=> $b} ($self->rows())) {
         my $parameter_name = $self->{'formulas'}->{'A'.$rownum};          my $parameter_name = $self->{'formulas'}->{'A'.$rownum};
         my $description = '';          my $description = $self->get_parm_name($parameter_name);
         if (exists($nice_parameter_name{$parameter_name})) {  
             $description = $nice_parameter_name{$parameter_name};  
         }  
         $self->csv_output_row($filehandle,$rownum,          $self->csv_output_row($filehandle,$rownum,
                               $parameter_name,$description);                                $parameter_name,$description);
     }      }
Line 575  sub excel_rows { Line 594  sub excel_rows {
     # Write each row      # Write each row
     foreach my $rownum (sort {$a <=> $b} ($self->rows())) {      foreach my $rownum (sort {$a <=> $b} ($self->rows())) {
         my $parameter_name = $self->{'formulas'}->{'A'.$rownum};          my $parameter_name = $self->{'formulas'}->{'A'.$rownum};
         my $description = '';          my $description = $self->get_parm_name($parameter_name);
         if (exists($nice_parameter_name{$parameter_name})) {  
             $description = $nice_parameter_name{$parameter_name};  
         }  
         $self->excel_output_row($worksheet,$rownum,$rows_output++,          $self->excel_output_row($worksheet,$rownum,$rows_output++,
                                 $parameter_name,$description);                                  $parameter_name,$description);
     }      }
Line 588  sub excel_rows { Line 604  sub excel_rows {
 ##  ##
 ## Routines to support assesscalc::compute  ## Routines to support assesscalc::compute
 ##  ##
 sub get_parm_names {  sub get_parm {
     my $self = shift;      my $self = shift;
     my @Mandatory_parameters = @_;      my @Mandatory_parameters = @_;
     my %parameters_and_names;      my %parameters;
     #      #
     my ($symap,$syid,$srcf) = &Apache::lonnet::decode_symb($self->{'symb'});      my ($symap,$syid,$srcf) = &Apache::lonnet::decode_symb($self->{'symb'});
     my @Metadata = split(/\,/,&Apache::lonnet::metadata($srcf,'keys'));      my @Metadata = split(/\,/,&Apache::lonnet::metadata($srcf,'keys'));
Line 600  sub get_parm_names { Line 616  sub get_parm_names {
         my $cleaned_name = $parm;          my $cleaned_name = $parm;
         $cleaned_name =~ s/^resource\./stores_/;          $cleaned_name =~ s/^resource\./stores_/;
         $cleaned_name =~ s/\./_/g;          $cleaned_name =~ s/\./_/g;
         my $display = &Apache::lonnet::metadata($srcf,          $parameters{$cleaned_name}=1;
                                                 $cleaned_name.'.display');  
         if (! $display) {  
             $display .= &Apache::lonnet::metadata($srcf,$cleaned_name.'.name');  
         }  
         $parameters_and_names{$cleaned_name}=$display;  
     }      }
     return (%parameters_and_names);      return (keys(%parameters));
   }
   
   sub get_parm_name {
       my $self = shift;
       my $parm = shift;
       my ($symap,$syid,$srcf) = &Apache::lonnet::decode_symb($self->{'symb'});
       my $display = &Apache::lonnet::metadata($srcf,$parm.'.display');
       if (! $display) {
    $display .= &Apache::lonnet::metadata($srcf,$parm.'.name');
       }
       return $display;
 }  }
   
 sub get_parameter_values {  sub get_parameter_values {
Line 627  sub get_parameter_values { Line 649  sub get_parameter_values {
     my $filename = $self->{'coursefilename'}.'_parms.db';      my $filename = $self->{'coursefilename'}.'_parms.db';
     if (tie(%parmhash,'GDBM_File',      if (tie(%parmhash,'GDBM_File',
             $self->{'coursefilename'}.'_parms.db',&GDBM_READER(),0640)) {              $self->{'coursefilename'}.'_parms.db',&GDBM_READER(),0640)) {
    my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($self->{'symb'});
    $mapname = &Apache::lonnet::deversion($mapname);
         foreach my $parmname (@Parameters) {          foreach my $parmname (@Parameters) {
             my $value = $self->parmval($parmname);              my $value = $self->parmval($parmname,$self->{'symb'},
          $self->{'name'},$self->{'domain'},
          $self->{'section'},undef,
          $mapname,$id,$fn,$self->{'groups'});
             $parameters{$parmname} =$value;              $parameters{$parmname} =$value;
         }          }
         untie(%parmhash);          untie(%parmhash);
Line 696  sub parameter_part_is_valid { Line 723  sub parameter_part_is_valid {
         return 1;          return 1;
     }      }
     #      #
     my (undef,$part) =       my ($start,@pieces)=split('_',$parameter);
         ($parameter =~ m/^(resource|stores|parameter)_([^_]+)_.*/);      if ( $start !~ m/^(resource|stores|parameter)$/) { return 0; }
     if (exists($self->{'Parts'})          &&       while (@pieces) {
         exists($self->{'Parts'}->{$part}) &&          pop(@pieces);
         $self->{'Parts'}->{$part} ) {          my $testpart=join('_',@pieces);
         return 1;   if (exists($self->{'Parts'}->{$testpart}) &&
     } else {      $self->{'Parts'}->{$testpart} ) {
         return 0;      return 1;
    }
     }      }
       return 0;
 }  }
   
 sub compute {  sub compute {
Line 730  sub compute { Line 759  sub compute {
     my %parameters;   # holds underscored parameters by name      my %parameters;   # holds underscored parameters by name
     #      #
     # Get the metadata fields and determine their proper names      # Get the metadata fields and determine their proper names
     my %nice_parm_names = $self->get_parm_names(@Mandatory_parameters);      my @parameters=$self->get_parm(@Mandatory_parameters);
     while (my($cleaned_name,$display) = each(%nice_parm_names)) {  
         $parameters{$cleaned_name}++;  
         $nice_parameter_name{$cleaned_name} = $display;  
     }  
     #      #
     # Get the values of the metadata fields      # Get the values of the metadata fields
     $self->ensure_current_caches();      $self->ensure_current_caches();
     %parameters = $self->get_parameter_values(keys(%parameters));      %parameters = $self->get_parameter_values(@parameters);
     #      #
     # Clean out unnecessary parameters      # Clean out unnecessary parameters
     foreach (keys(%parameters)) {      foreach (keys(%parameters)) {
Line 786  sub compute { Line 811  sub compute {
         $value = 'q{'.$value.'}' if ($value =~/([^\d\.]|\.\.)/);          $value = 'q{'.$value.'}' if ($value =~/([^\d\.]|\.\.)/);
         $c{$parm} = $value;          $c{$parm} = $value;
     }      }
       foreach my $cell (grep(/^A/,keys(%f))) {
           # Clean out any bad formulas
    next if (exists($c{$f{$cell}}));
    next if ($cell eq 'A0');
    delete($f{$cell});
       }
     $self->formulas(\%f);      $self->formulas(\%f);
     $self->constants(\%c);      $self->constants(\%c);
     $self->calcsheet();      $self->calcsheet();
Line 821  sub sett { Line 852  sub sett {
             # Replace 'A0' with the value from 'A0'              # Replace 'A0' with the value from 'A0'
             $t{$cell}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$sheet_values\{\'$2\'\}/g;              $t{$cell}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$sheet_values\{\'$2\'\}/g;
             # Replace parameters              # Replace parameters
             $t{$cell}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.$self->expandnamed($2)/ge;              $t{$cell}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.$self->expandnamed($2)/sge;
         }          }
     }      }
     #      #
Line 829  sub sett { Line 860  sub sett {
     while (my ($cell,$formula) = each(%{$self->{'formulas'}})) {      while (my ($cell,$formula) = each(%{$self->{'formulas'}})) {
  next if ($cell =~ /template_/);   next if ($cell =~ /template_/);
         if ($cell =~ /^A/ && $cell ne 'A0') {          if ($cell =~ /^A/ && $cell ne 'A0') {
             if ($formula !~ /^\!/) {      if ($formula !~ /^\!/ 
    && exists($self->{'constants'}->{$formula}) 
    && $self->{'constants'}->{$formula} ne ''
    ) {
  $Apache::Spreadsheet::sheet_values{$cell}=   $Apache::Spreadsheet::sheet_values{$cell}=
     eval($self->{'constants'}->{$formula});      eval($self->{'constants'}->{$formula});
             }              }
Line 837  sub sett { Line 871  sub sett {
             $t{$cell}=$formula;              $t{$cell}=$formula;
             $t{$cell}=~s/\.\.+/\,/g;              $t{$cell}=~s/\.\.+/\,/g;
             $t{$cell}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$sheet_values\{\'$2\'\}/g;              $t{$cell}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$sheet_values\{\'$2\'\}/g;
             $t{$cell}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.$self->expandnamed($2)/ge;              $t{$cell}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.$self->expandnamed($2)/sge;
         }          }
     }      }
     # Put %t into the safe space      # Put %t into the safe space

Removed from v.1.43  
changed lines
  Added in v.1.58


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