--- loncom/interface/spreadsheet/Spreadsheet.pm 2004/02/24 17:02:04 1.35 +++ loncom/interface/spreadsheet/Spreadsheet.pm 2005/04/29 18:13:07 1.43 @@ -1,5 +1,5 @@ # -# $Id: Spreadsheet.pm,v 1.35 2004/02/24 17:02:04 albertel Exp $ +# $Id: Spreadsheet.pm,v 1.43 2005/04/29 18:13:07 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -86,6 +86,15 @@ sub new { my ($stype) = ($class =~ /Apache::(.*)$/); # my ($name,$domain,$filename,$usymb)=@_; + if (defined($usymb) && ref($usymb)) { + $usymb = $usymb->symb; + } + if (! defined($name) || $name eq '') { + $name = $env{'user.name'}; + } + if (! defined($domain) || $domain eq '') { + $domain = $env{'user.domain'}; + } # my $self = { name => $name, @@ -94,12 +103,12 @@ sub new { symb => $usymb, errorlog => '', maxrow => 0, - cid => $ENV{'request.course.id'}, - cnum => $ENV{'course.'.$ENV{'request.course.id'}.'.num'}, - cdom => $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - chome => $ENV{'course.'.$ENV{'request.course.id'}.'.home'}, - coursedesc => $ENV{'course.'.$ENV{'request.course.id'}.'.description'}, - coursefilename => $ENV{'request.course.fn'}, + cid => $env{'request.course.id'}, + cnum => $env{'course.'.$env{'request.course.id'}.'.num'}, + cdom => $env{'course.'.$env{'request.course.id'}.'.domain'}, + chome => $env{'course.'.$env{'request.course.id'}.'.home'}, + coursedesc => $env{'course.'.$env{'request.course.id'}.'.description'}, + coursefilename => $env{'request.course.fn'}, # # Flags temporary => 0, # true if this sheet has been modified but not saved @@ -123,8 +132,8 @@ sub new { # # Load in the spreadsheet definition $self->filename($filename); - if (exists($ENV{'form.workcopy'}) && - $self->{'type'} eq $ENV{'form.workcopy'}) { + if (exists($env{'form.workcopy'}) && + $self->{'type'} eq $env{'form.workcopy'}) { $self->load_tmp(); } else { $self->load(); @@ -151,8 +160,8 @@ sub filename { $newfilename !~ /\w/ || $newfilename eq '') { my $key = 'course.'.$self->{'cid'}.'.spreadsheet_default_'. $self->{'type'}; - if (exists($ENV{$key}) && $ENV{$key} ne '') { - $newfilename = $ENV{$key}; + if (exists($env{$key}) && $env{$key} ne '') { + $newfilename = $env{$key}; } else { $newfilename = 'default_'.$self->{'type'}; } @@ -250,10 +259,10 @@ sub initialize_spreadsheet_package { sub load_spreadsheet_expirationdates { undef %expiredates; - my $cid=$ENV{'request.course.id'}; + my $cid=$env{'request.course.id'}; my @tmp = &Apache::lonnet::dump('nohist_expirationdates', - $ENV{'course.'.$cid.'.domain'}, - $ENV{'course.'.$cid.'.num'}); + $env{'course.'.$cid.'.domain'}, + $env{'course.'.$cid.'.num'}); if (lc($tmp[0]) !~ /^error/){ %expiredates = @tmp; } @@ -307,6 +316,9 @@ Returns the safe space required by a Spr sub initialize_safe_space { my $self = shift; + my $usection = &Apache::lonnet::getsection($self->{'domain'}, + $self->{'name'}, + $env{'request.course.id'}); if (! defined($safeeval)) { $safeeval = new Safe(shift); my $safehole = new Safe::Hole; @@ -314,7 +326,7 @@ sub initialize_safe_space { $safeeval->permit(":base_math"); $safeeval->permit("sort"); $safeeval->deny(":base_io"); - $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&EXT'); + $safehole->wrap(\&Apache::lonnet::EXT,$safeeval,'&Apache::lonnet::EXT'); $safehole->wrap(\&mask,$safeeval,'&mask'); $safeeval->share('$@'); my $code=<<'ENDDEFS'; @@ -373,6 +385,25 @@ $errormsg = ''; =pod +=item EXT(parameter) + +Calls the system EXT function to determine the value of the given parameter. + +=cut + +#------------------------------------------------------- +sub EXT { + my ($parameter) = @_; + return '' if (! defined($parameter) || $parameter eq ''); + $parameter =~ s/^parameter\./resource\./; + my $value = &Apache::lonnet::EXT($parameter,$symb,$domain,$name,$usection); + return $value; +} + +#------------------------------------------------------- + +=pod + =item NUM(range) returns the number of items in the range. @@ -565,7 +596,7 @@ sub SUMMAX { foreach (grep eval("/$mask/"),keys(%sheet_values)) { push (@inside,$sheet_values{$_}); } - @inside=sort(@inside); + @inside=sort {$a <=> $b} (@inside); my $sum=0; my $i; for ($i=$#inside;(($i>$#inside-$num) && ($i>=0));$i--) { $sum+=$inside[$i]; @@ -592,7 +623,7 @@ sub SUMMIN { foreach (grep eval("/$mask/"),keys(%sheet_values)) { $inside[$#inside+1]=$sheet_values{$_}; } - @inside=sort(@inside); + @inside=sort {$a <=> $b} (@inside); my $sum=0; my $i; for ($i=0;(($i<$num) && ($i<=$#inside));$i++) { $sum+=$inside[$i]; @@ -690,10 +721,11 @@ ENDDEFS # Place some of the %$self items into the safe space except the safe space # itself my $initstring = ''; - foreach (qw/name domain type usymb cid csec coursefilename + foreach (qw/name domain type symb cid csec coursefilename cnum cdom chome uhome/) { $initstring.= qq{\$$_="$self->{$_}";}; } + $initstring.=qq{\$usection="$usection";}; $self->{'safe'}->reval($initstring); return $self; } @@ -905,7 +937,8 @@ sub sett { $t{$cell}=~s/(^|[^\"\'])([A-Za-z]\d+)/$1\$sheet_values\{\'$2\'\}/g; $t{$cell}=~s/(^|[^\"\'])\[([^\]]+)\]/$1.$self->expandnamed($2)/ge; } elsif ( $col =~ /^[A-Z]$/ ) { - if ($formula !~ /^\!/ && exists($self->{'constants'}->{$cell})) { + if ($formula !~ /^\!/ && exists($self->{'constants'}->{$cell}) + && $self->{'constants'}->{$cell} ne '') { my $data = $self->{'constants'}->{$cell}; $t{$cell} = $data; } @@ -1190,7 +1223,7 @@ sub display { my ($r) = @_; my $outputmode = 'html'; foreach ($self->output_options()) { - if ($ENV{'form.output_format'} eq $_->{'value'}) { + if ($env{'form.output_format'} eq $_->{'value'}) { $outputmode = $_->{'value'}; last; } @@ -1234,7 +1267,7 @@ sub html_export_row { my $self = shift(); my ($color) = @_; $color = '#CCCCFF' if (! defined($color)); - my $allowed = &Apache::lonnet::allowed('mgr',$ENV{'request.course.id'}); + my $allowed = &Apache::lonnet::allowed('mgr',$env{'request.course.id'}); my $row_html; my @rowdata = $self->get_row(0); foreach my $cell (@rowdata) { @@ -1251,7 +1284,7 @@ sub html_export_row { sub html_template_row { my $self = shift(); - my $allowed = &Apache::lonnet::allowed('mgr',$ENV{'request.course.id'}); + my $allowed = &Apache::lonnet::allowed('mgr',$env{'request.course.id'}); my ($num_uneditable,$importcolor) = @_; my $row_html; my @rowdata = $self->get_template_row(); @@ -1288,7 +1321,7 @@ sub html_editable_cell { } elsif ($value =~ /^\s*$/ ) { $value = '<font color="'.$bgcolor.'">#</font>'; } else { - $value = &HTML::Entities::encode($value) if ($value !~/ /); + $value = &HTML::Entities::encode($value,'<>&"') if ($value !~/ /); } return $value if (! $allowed); # @@ -1311,14 +1344,14 @@ sub html_editable_cell { sub html_uneditable_cell { my ($cell,$bgcolor) = @_; my $value = (defined($cell) ? $cell->{'value'} : ''); - $value = &HTML::Entities::encode($value) if ($value !~/ /); + $value = &HTML::Entities::encode($value,'<>&"') if ($value !~/ /); return ' '.$value.' '; } sub html_row { my $self = shift(); my ($num_uneditable,$row,$exportcolor,$importcolor) = @_; - my $allowed = &Apache::lonnet::allowed('mgr',$ENV{'request.course.id'}); + my $allowed = &Apache::lonnet::allowed('mgr',$env{'request.course.id'}); my @rowdata = $self->get_row($row); my $num_cols_output = 0; my $row_html; @@ -1342,7 +1375,7 @@ sub html_row { sub html_header { my $self = shift; - return '' if (! $ENV{'request.role.adv'}); + return '' if (! $env{'request.role.adv'}); return "<table>\n". '<tr><th align="center">'.&mt('Output Format').'</th></tr>'."\n". '<tr><td>'.$self->output_selector()."</td></tr>\n". @@ -1367,10 +1400,10 @@ sub output_selector { my $self = shift(); my $output_selector = '<select name="output_format" size="3">'."\n"; my $default = 'html'; - if (exists($ENV{'form.output_format'})) { - $default = $ENV{'form.output_format'} + if (exists($env{'form.output_format'})) { + $default = $env{'form.output_format'} } else { - $ENV{'form.output_format'} = $default; + $env{'form.output_format'} = $default; } foreach ($self->output_options()) { $output_selector.='<option value="'.$_->{'value'}.'"'; @@ -1401,31 +1434,6 @@ sub excel_output_row { return; } -sub create_excel_spreadsheet { - my $self = shift; - my ($r) = @_; - my $filename = '/prtspool/'. - $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. - time.'_'.rand(1000000000).'.xls'; - my $workbook = Spreadsheet::WriteExcel->new('/home/httpd'.$filename); - if (! defined($workbook)) { - $r->log_error("Error creating excel spreadsheet $filename: $!"); - $r->print(&mt("Problems creating new Excel file. ". - "This error has been logged. ". - "Please alert your LON-CAPA administrator")); - return undef; - } - # - # The excel spreadsheet stores temporary data in files, then put them - # together. If needed we should be able to disable this (memory only). - # The temporary directory must be specified before calling 'addworksheet'. - # File::Temp is used to determine the temporary directory. - $workbook->set_tempdir('/home/httpd/perl/tmp'); - # - # Determine the name to give the worksheet - return ($workbook,$filename); -} - # # This routine is just a stub sub outsheet_htmlclasslist { @@ -1446,8 +1454,8 @@ sub outsheet_excel { # $r->print("<h2>".&mt('Preparing Excel Spreadsheet')."</h2>"); # - # Create excel worksheet - my ($workbook,$filename) = $self->create_excel_spreadsheet($r); + # Create excel workbook + my ($workbook,$filename,$format)=&Apache::loncommon::create_workbook($r); return if (! defined($workbook)); # # Create main worksheet @@ -1458,16 +1466,18 @@ sub outsheet_excel { # Write excel header foreach my $value ($self->get_title()) { $cols_output = 0; - $worksheet->write($rows_output++,$cols_output,$value); + $worksheet->write($rows_output++,$cols_output,$value,$format->{'h1'}); } $rows_output++; # skip a line # # Write summary/export row $cols_output = 0; - $self->excel_output_row($worksheet,0,$rows_output++,'Summary'); + $self->excel_output_row($worksheet,0,$rows_output++,'Summary', + $format->{'b'}); $rows_output++; # skip a line # - $self->excel_rows($connection,$worksheet,$cols_output,$rows_output); + $self->excel_rows($connection,$worksheet,$cols_output,$rows_output, + $format); # # # Close the excel file @@ -1495,7 +1505,7 @@ sub outsheet_csv { # # Open the csv file my $filename = '/prtspool/'. - $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'. + $env{'user.name'}.'_'.$env{'user.domain'}.'_'. time.'_'.rand(1000000000).'.csv'; my $file; unless ($file = Apache::File->new('>'.'/home/httpd'.$filename)) { @@ -1744,7 +1754,7 @@ sub save { my $reply = &Apache::lonnet::put($filename,\%f,$cdom,$cnum); return $reply if ($reply ne 'ok'); $reply = &Apache::lonnet::put($stype.'_spreadsheets', - {$filename => $ENV{'user.name'}.'@'.$ENV{'user.domain'}}, + {$filename => $env{'user.name'}.'@'.$env{'user.domain'}}, $cdom,$cnum); return $reply if ($reply ne 'ok'); if ($makedef) { @@ -1770,8 +1780,8 @@ sub save { sub save_tmp { my $self = shift; - my $filename=$ENV{'user.name'}.'_'. - $ENV{'user.domain'}.'_spreadsheet_'.$self->{'symb'}.'_'. + my $filename=$env{'user.name'}.'_'. + $env{'user.domain'}.'_spreadsheet_'.$self->{'symb'}.'_'. $self->{'filename'}; $filename=~s/\W/\_/g; $filename=$Apache::lonnet::tmpdir.$filename.'.tmp'; @@ -1790,8 +1800,8 @@ sub save_tmp { sub load_tmp { my $self = shift; - my $filename=$ENV{'user.name'}.'_'. - $ENV{'user.domain'}.'_spreadsheet_'.$self->{'symb'}.'_'. + my $filename=$env{'user.name'}.'_'. + $env{'user.domain'}.'_spreadsheet_'.$self->{'symb'}.'_'. $self->{'filename'}; $filename=~s/\W/\_/g; $filename=$Apache::lonnet::tmpdir.$filename.'.tmp';