--- loncom/interface/spreadsheet/Spreadsheet.pm 2006/03/05 21:35:10 1.64 +++ loncom/interface/spreadsheet/Spreadsheet.pm 2014/02/28 19:20:11 1.84 @@ -1,5 +1,5 @@ # -# $Id: Spreadsheet.pm,v 1.64 2006/03/05 21:35:10 bowersj2 Exp $ +# $Id: Spreadsheet.pm,v 1.84 2014/02/28 19:20:11 bisitz Exp $ # # Copyright Michigan State University Board of Trustees # @@ -60,6 +60,9 @@ use HTML::TokeParser; use Spreadsheet::WriteExcel; use Time::HiRes; use Apache::lonlocal; +use lib '/home/httpd/lib/perl/'; +use LONCAPA; + ## ## Package Variables @@ -85,7 +88,7 @@ sub new { my $class = ref($this) || $this; my ($stype) = ($class =~ /Apache::(.*)$/); # - my ($name,$domain,$filename,$usymb)=@_; + my ($name,$domain,$filename,$usymb,$section,$groups)=@_; if (defined($usymb) && ref($usymb)) { $usymb = $usymb->symb; } @@ -95,10 +98,22 @@ sub new { if (! defined($domain) || $domain eq '') { $domain = $env{'user.domain'}; } + if (! defined($section) || $section eq '') { + $section = &Apache::lonnet::getsection($domain,$name, + $env{'request.course.id'}); + } + if (! defined($groups)) { + + my @usersgroups = &Apache::lonnet::get_users_groups($domain,$name, + $env{'request.course.id'}); + $groups = \@usersgroups; + } # my $self = { name => $name, domain => $domain, + section => $section, + groups => $groups, type => $stype, symb => $usymb, errorlog => '', @@ -157,16 +172,20 @@ sub filename { $newfilename = 'default_'.$self->{'type'}; } } - if ($newfilename !~ /\w/ || $newfilename =~ /^\W*$/) { - $newfilename = 'default_'.$self->{'type'}; - } - if ($newfilename !~ /^default\.$self->{'type'}$/ && - $newfilename !~ /^\/res\/(.*)spreadsheet$/) { - if ($newfilename !~ /_$self->{'type'}$/) { - $newfilename =~ s/[\s_]*$//; - $newfilename .= '_'.$self->{'type'}; - } - } + if ($newfilename eq &mt('LON-CAPA Standard')) { + undef($newfilename); + } else { + if ($newfilename !~ /\w/ || $newfilename =~ /^\W*$/) { + $newfilename = 'default_'.$self->{'type'}; + } + if ($newfilename !~ /^default\.$self->{'type'}$/ && + $newfilename !~ /^\/res\/(.*)spreadsheet$/) { + if ($newfilename !~ /_$self->{'type'}$/) { + $newfilename =~ s/[\s_]*$//; + $newfilename .= '_'.$self->{'type'}; + } + } + } $self->{'filename'} = $newfilename; return; } @@ -191,8 +210,8 @@ sub make_default { {'spreadsheet_default_'.$self->{'type'} => $self->filename()}, $self->{'cdom'},$self->{'cnum'}); return $result if ($result ne 'ok'); - &Apache::lonnet::appenv('course.'.$self->{'cid'}.'.spreadsheet_default_'. - $self->{'type'} => $self->filename()); + &Apache::lonnet::appenv({'course.'.$self->{'cid'}.'.spreadsheet_default_'. + $self->{'type'} => $self->filename()}); my $symb = $self->{'symb'}; $symb = '' if (! defined($symb)); &Apache::lonnet::expirespread('','',$self->{'type'},$symb); @@ -656,6 +675,21 @@ sub MAXPARM { return $max; } + +=pod + +=item PARM(parametername) + +Returns the value of the parameter matching the input parameter name. +parametername should be a string such as 'parameter_1_opendate'. + +=cut + +#------------------------------------------------------- +sub PARM { + return $c{$_[0]}; +} + #------------------------------------------------------- =pod @@ -692,7 +726,7 @@ sub get_values { my @num=($ld..$ud); foreach my $a (@alpha) { foreach my $n (@num) { - if (exists($sheet_values{$a.$n})) { + if ((exists($sheet_values{$a.$n})) && ($sheet_values{$a.$n} ne '')) { push(@values,$sheet_values{$a.$n}); } } @@ -708,8 +742,10 @@ sub get_values { $alpha=qq/[$la-$ua]/; } my $expression = '^'.$alpha.$num.'$'; - foreach (grep /$expression/,keys(%sheet_values)) { - push(@values,$sheet_values{$_}); + foreach my $item (grep(/$expression/,keys(%sheet_values))) { + unless ($sheet_values{$item} eq '') { + push(@values,$sheet_values{$item}); + } } return \@values; } @@ -722,7 +758,7 @@ sub calc { $notfinished=0; while (my ($cell,$value) = each(%t)) { my $old=$sheet_values{$cell}; - #$sheet_values{$cell}=eval $value; + $sheet_values{$cell}=eval $value; # $errorlog .= $cell.' = '.$old.'->'.$sheet_values{$cell}."\n"; if ($@) { undef %sheet_values; @@ -738,7 +774,7 @@ sub calc { $depth++; if ($depth>100) { undef %sheet_values; - return $lastcalc.': Maximum calculation depth exceeded'; + return $lastcalc.': '.&mt('Maximum calculation depth exceeded'); } } return 'okay'; @@ -786,18 +822,20 @@ sub expandnamed { my $self = shift; my $expression=shift; if ($expression=~/^\&/) { - my ($func,$var,$formula)=($expression=~/^\&(\w+)\(([^\;]+)\;(.*)\)/); + my ($func,$var,$formula)=($expression=~/^\&(\w+)\(([^\;]+)\;(.*)\)/s); my @vars=split(/\W+/,$formula); + # make the list uniq + @vars = keys(%{{ map { $_ => 1 } @vars }}); my %values=(); foreach my $varname ( @vars ) { if ($varname=~/^(parameter|stores|timestamp)/) { $formula=~s/$varname/'$c{\''.$varname.'\'}'/ge; - $varname=~s/$var/\([\\w:\\- ]\+\)/g; - foreach (keys(%{$self->{'constants'}})) { - if ($_=~/$varname/) { - $values{$1}=1; - } - } + $varname=~s/$var/\([\\w:\\- ]\+\)/g; + foreach (keys(%{$self->{'constants'}})) { + if ($_=~/$varname/) { + $values{$1}=1; + } + } } } if ($func eq 'EXPANDSUM') { @@ -835,7 +873,7 @@ sub expandnamed { $returnvalue = $values[0]; } elsif (scalar(@matches) > 0) { # more than one match. Look for a concise one - $returnvalue = "'non-unique parameter name : $expression'"; + $returnvalue = "'".&mt('non-unique parameter name: [_1]',$expression).'"'; for (my $i=0; $i<=$#matches;$i++) { if ($matches[$i] =~ /^$expression$/) { # why do we not do this lookup here? @@ -845,7 +883,7 @@ sub expandnamed { } else { # There was a negative number of matches, which indicates # something is wrong with reality. Better warn the user. - $returnvalue = '"bizzare parameter: '.$expression.'"'; + $returnvalue = "'".&mt('bizzarre parameter: [_1]',$expression)."'"; } return $returnvalue; } @@ -871,7 +909,7 @@ sub sett { # Replace 'A0' with the value from 'A0' $t{$cell}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$sheet_values\{\'$2\'\}/g; # Replace parameters - $t{$cell}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.$self->expandnamed($2)/ge; + $t{$cell}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.$self->expandnamed($2)/sge; } } # @@ -883,7 +921,7 @@ sub sett { $t{$cell}=$formula; $t{$cell}=~s/\.\.+/\,/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; } elsif ( $col =~ /^[A-Z]$/ ) { if ($formula !~ /^\!/ && exists($self->{'constants'}->{$cell}) && $self->{'constants'}->{$cell} ne '') { @@ -894,7 +932,7 @@ sub sett { $t{$cell}=$formula; $t{$cell}=~s/\.\.+/\,/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; } } %{$self->{'safe'}->varglob('t')}=%t; @@ -1229,9 +1267,9 @@ sub html_report_error { my $self = shift(); my $Str = ''; if ($self->badcalc()) { - $Str = '

'. + $Str = '

'. &mt('An error occurred while calculating this spreadsheet'). - "

\n". + "

\n". '
'.$self->calcerror()."
\n"; } return $Str; @@ -1271,8 +1309,8 @@ sub html_template_row { $row_html .= ''. &html_uneditable_cell($cell,'#FFDDDD',$allowed).''; } else { - $row_html .= ''. - &html_editable_cell($cell,'#EOFFDD',$allowed, + $row_html .= ''. + &html_editable_cell($cell,'#E0FFDD',$allowed, $self->{outputmode} eq 'source').''; } } @@ -1290,15 +1328,13 @@ sub html_editable_cell { } $name = '' if (! defined($name)); $formula = '' if (! defined($formula)); - if ($showsource) - { + if ($showsource) { if (!defined($formula) || $formula =~ /^\s*$/) { $value = '#'; } else { $value = &HTML::Entities::encode($formula, '<>&"'); } - } - elsif (! defined($value)) { + } elsif (! defined($value)) { $value = '#'; if ($formula ne '') { $value = 'undefined value'; @@ -1350,7 +1386,7 @@ sub html_row { $row_html .= ''; $row_html .= &html_uneditable_cell($cell,'#FFDDDD'); } else { - $row_html .= ''; + $row_html .= ''; $row_html .= &html_editable_cell($cell,'#E0FFDD',$allowed, $self->{outputmode} eq 'source'); } @@ -1396,7 +1432,7 @@ sub output_selector { foreach ($self->output_options()) { $output_selector.='\n"; } @@ -1473,7 +1509,7 @@ sub outsheet_excel { # # Write a link to allow them to download it $r->print('
'. - 'Your Excel spreadsheet.'."\n"); + ''.&mt('Your Excel spreadsheet').''."\n"); return; } @@ -1491,16 +1527,20 @@ sub outsheet_csv { my $csvdata = ''; my @Values; # - # Open the csv file + # Open the CSV file my $filename = '/prtspool/'. $env{'user.name'}.'_'.$env{'user.domain'}.'_'. time.'_'.rand(1000000000).'.csv'; my $file; unless ($file = Apache::File->new('>'.'/home/httpd'.$filename)) { $r->log_error("Couldn't open $filename for output $!"); - $r->print(&mt("Problems occured in writing the csv file. ". - "This error has been logged. ". - "Please alert your LON-CAPA administrator.")); + $r->print( + '

' + .&mt('Problems occurred in writing the CSV file.') + .' '.&mt('This error has been logged.') + .' '.&mt('Please alert your LON-CAPA administrator.') + .'

' + ); $r->print("
\n".$csvdata."
\n"); return 0; } @@ -1513,7 +1553,7 @@ sub outsheet_csv { # Output the body of the spreadsheet $self->csv_rows($connection,$file); # - # Close the csv file + # Close the CSV file close($file); $r->print('

'. ''.&mt('Your CSV spreadsheet.').''."\n"); @@ -1655,8 +1695,10 @@ sub load { my $sheetxml=&Apache::lonnet::getfile (&Apache::lonnet::filelocation('',$filename)); if ($sheetxml == -1) { - $sheetxml='"Error loading spreadsheet ' - .$self->filename().'"'; + $sheetxml=''. + &mt('Error loading spreadsheet [_1]', + '"'.$self->filename().'"'). + ''; } ($formulas,undef) = &parse_sheet(\$sheetxml); # Get just the filename and set the sheets filename @@ -1671,7 +1713,8 @@ sub load { # Load the spreadsheet definition file from the save file my %tmphash = &Apache::lonnet::dump($filename,$cdom,$cnum); my ($tmp) = keys(%tmphash); - if ($tmp !~ /^(con_lost|error|no_such_host)/i) { + if (%tmphash + && $tmp !~ /^(con_lost|error|no_such_host)/i) { while (my ($cell,$formula) = each(%tmphash)) { $formulas->{$cell}=$formula; } @@ -1774,16 +1817,14 @@ sub save { {'spreadsheet_default_'.$stype => $filename }, $cdom,$cnum); return $reply if ($reply ne 'ok'); - &Apache::lonnet::appenv('course.'.$self->{'cid'}.'.spreadsheet_default_'. - $self->{'type'} => $self->filename()); + &Apache::lonnet::appenv({'course.'.$self->{'cid'}.'.spreadsheet_default_'. + $self->{'type'} => $self->filename()}); } - if ($self->is_default()) { - if ($self->{'type'} eq 'studentcalc') { - &Apache::lonnet::expirespread('','','studentcalc',''); - } elsif ($self->{'type'} eq 'assesscalc') { - &Apache::lonnet::expirespread('','','assesscalc',''); - &Apache::lonnet::expirespread('','','studentcalc',''); - } + if ($self->{'type'} eq 'studentcalc') { + &Apache::lonnet::expirespread('','','studentcalc',''); + } elsif ($self->{'type'} eq 'assesscalc') { + &Apache::lonnet::expirespread('','','assesscalc',''); + &Apache::lonnet::expirespread('','','studentcalc',''); } return $reply; } @@ -1805,8 +1846,8 @@ sub save_tmp { my %f = $self->formulas(); while( my ($cell,$formula) = each(%f)) { next if ($formula eq 'import'); - print $fh &Apache::lonnet::escape($cell)."=". - &Apache::lonnet::escape($formula)."\n"; + print $fh &escape($cell)."=". + &escape($formula)."\n"; } $fh->close(); } @@ -1824,8 +1865,8 @@ sub load_tmp { while (<$spreadsheet_file>) { chomp; my ($cell,$formula) = split(/=/); - $cell = &Apache::lonnet::unescape($cell); - $formula = &Apache::lonnet::unescape($formula); + $cell = &unescape($cell); + $formula = &unescape($formula); $formulas{$cell} = $formula; } $spreadsheet_file->close(); @@ -1868,14 +1909,13 @@ sub othersheets { my ($stype) = @_; $stype = $self->{'type'} if (! defined($stype) || $stype !~ /calc$/); # - my @alternatives=(); + my @alternatives=(&mt('Default'), &mt('LON-CAPA Standard')); my %results=&Apache::lonnet::dump($stype.'_spreadsheets', $self->{'cdom'}, $self->{'cnum'}); my ($tmp) = keys(%results); - if ($tmp =~ /^(con_lost|error|no_such_host)/i ) { - @alternatives = (&mt('Default')); - } else { - @alternatives = (&mt('Default'), sort (keys(%results))); + if (%results + && $tmp !~ /^(con_lost|error|no_such_host)/i ) { + push(@alternatives, sort(keys(%results))); } return @alternatives; }