=head1 NAME
EPrints::Plugin::Export::Grid2
=cut
package EPrints::Plugin::Export::Grid2;
use Data::Dumper;
use EPrints::Plugin::Export;
@ISA = ( "EPrints::Plugin::Export::Grid" );
use strict;
$EPrints::Plugin::Import::DISABLE = 1;
sub new
{
my( $class, %opts ) = @_;
my $self = $class->SUPER::new( %opts );
$self->{name} = "Grid 2 (abstract)";
$self->{accept} = [ 'dataobj/*', 'list/*', ];
$self->{visible} = "none";
$self->{advertise} = 0;
return $self;
}
sub fields
{
my( $self, $dataset ) = @_;
# skip compound, subobjects
#return grep { !$_->is_virtual } $dataset->fields;
my @fieldnames;
foreach my $f ( $dataset->fields )
{
if( !$f->is_virtual )
{
push @fieldnames, $f->name;
}
}
return \@fieldnames;
}
sub header_row
{
my( $self, %opts ) = @_;
my $fields = $opts{fields} ||= [$self->fields($opts{list}->{dataset})];
my $ds = $opts{list}->{dataset};
my @names;
foreach my $f (@$fields)
{
if( defined $opts{custom_export} && defined $opts{custom_export}->{$f} )
{
push @names, $ds->repository->html_phrase( "exportfieldoptions:$f" );
}
else
{
my $field = EPrints::Utils::field_from_config_string( $ds, $f );
if ($field->isa("EPrints::MetaField::Multipart"))
{
my $parent_name = $field->render_name;
if( $field->isa( "EPrints::MetaField::Name" )) #need to deal with legacy phrase id's
{
foreach my $bit ( $field->get_input_bits() )
{
$bit = "given_names" if( $bit eq "given" );
$bit = "family_names" if( $bit eq "family" );
my $custom_phrase = $field->name . "_" . $bit;
if( $ds->repository->get_lang->has_phrase( $custom_phrase ) ) #allow a custom phrase to be used
{
push @names, $ds->repository->html_phrase( $custom_phrase );
}
else
{
push @names, $parent_name . ": " . $ds->repository->html_phrase( "lib/metafield:".$bit );
}
}
}
else
{
my $name = $field->name;
push @names, map {
$name . '.' . $_->{sub_name}
} @{$field->property("fields_cache")};
}
}
elsif( $field->isa("EPrints::MetaField::Compound" ) )
{
foreach my $sub_field (@{$field->property("fields_cache")})
{
my $custom_phrase = $field->name . "_" . $sub_field->name;
if( $ds->repository->get_lang->has_phrase( $custom_phrase ) ) #allow a custom phrase to be used
{
push @names, $ds->repository->html_phrase( $custom_phrase );
}
else
{
push @names, $field->render_name . ": " . $sub_field->render_name;
}
}
}
else
{
push @names, $field->render_name;
}
}
}
return @names;
}
sub dataobj_to_rows
{
my( $self, $dataobj, %opts ) = @_;
my $main_dataobj = $dataobj; #store dataobj for future reference
my $fields = $opts{fields} || [$self->fields($dataobj->{dataset})];
my $ds = $opts{list}->{dataset};
my @rows = ([]);
foreach my $fname (@$fields)
{
#reset dataobj to main dataobj
$dataobj = $main_dataobj;
#get the field from the id
my $field;
my @fnames = split( /\./, $fname );
my $sub_dataobj_values = [];
if( scalar( @fnames > 1 ) ) #a field of another dataset, e.g. documents.content
{
$field = $ds->get_field( $fnames[0] ); #first get the field
if( $field->is_type( "subobject", "itemref" ) ) #if the field belongs to another dataset
{
my $sub_ds_id = $field->get_property( "datasetid" );
my $multiple = $field->get_property( "multiple" );
if( $multiple )
{
my @sub_dataobjs;
#get the dataobjs of this field
if( $sub_ds_id eq "document" ) #documents represent a special case of sub object - we don't want volatile documents (probably)
{
@sub_dataobjs = $dataobj->get_all_documents;
}
else
{
foreach my $sub_obj ( @{$dataobj->value( $fnames[0] )} )
{
push @sub_dataobjs, $field->get_item( $dataobj->repository, $sub_obj );
}
}
#and build up an array of these sub dataobj's values
foreach my $obj ( @sub_dataobjs ) #get the values we are requesting of the dataobjects
{
#check for a custom renderer
my $value;
if( defined $opts{custom_export} && defined $opts{custom_export}->{$fname} )
{
$value = $opts{custom_export}->{$fname}->( $obj, $opts{plugin} );
}
else
{
$field = EPrints::Utils::field_from_config_string( $obj->dataset, $fnames[1] );
if( $field->get_property( "virtual" ) ) #virtual fields need rendering
{
$value = EPrints::Utils::tree_to_utf8( $obj->render_value( $fnames[1] ) );
}
else #regular field values can simply be retrieved
{
$value = $field->get_value( $obj );
}
}
push @{$sub_dataobj_values}, $value;
}
}
else #we only have one sub-object,
{
my $sub_obj = $field->get_item( $dataobj->repository, $dataobj->value( $fnames[0] ) ); #get the subobject
$field = EPrints::Utils::field_from_config_string( $sub_obj->dataset, $fnames[1] ); #get the subobjects field
my $value = $field->get_value( $sub_obj ); #get the subobjects value for this field
push @{$sub_dataobj_values}, $value;
}
}
}
my $i = @{$rows[0]};
my $_rows;
if( EPrints::Utils::is_set( $field ) ) #we already have our values
{
if( scalar @{$sub_dataobj_values} > 0 )
{
$_rows = $self->value_to_rows($field, $sub_dataobj_values);
}
else #there's no results, but we still need to add an empty cell to the spreadsheet
{
$_rows = $self->value_to_rows($field, undef);
}
}
else #we need to retrieve our values for this field from our dataobj (or sub_dataobj)
{
my $value;
if( defined $opts{custom_export} && defined $opts{custom_export}->{$fname} ) #we have a custom exporter
{
$value = $opts{custom_export}->{$fname}->( $dataobj, $opts{plugin} );
$_rows = $self->custom_value_to_rows( $value );
}
else #just get the field's usual value
{
$field = EPrints::Utils::field_from_config_string( $ds, $fname );
if( $field->get_property( "virtual" ) ) #virtual fields need rendering
{
$value = EPrints::Utils::tree_to_utf8( $dataobj->render_value( $fname ) );
}
else #regular field values can simply be retrieved
{
$value = $field->get_value( $dataobj );
}
$_rows = $self->value_to_rows($field, $value);
}
}
foreach my $j (0..$#$_rows)
{
foreach my $_i (0..$#{$_rows->[$j]})
{
$rows[$j][$i+$_i] = $_rows->[$j][$_i];
}
}
}
# generate complete rows
if($opts{plugin}->param( "multiline_repeat" )) #we want each column to repeat for each row
{
foreach my $i (0..(scalar @rows)-1)
{
foreach my $j (0..$#{$rows[0]})
{
$rows[$i][$j] ||= $rows[0][$j];
}
}
}
else #we don't want repeating values in the columns
{
for(@rows) {
$_->[0] = $rows[0][0]; #first element of this array equals the first element of the first row
$_->[$#{$rows[0]}] ||= undef;
}
}
return \@rows;
}
sub value_to_rows
{
my ($self, $field, $value) = @_;
my @rows;
if (ref($value) eq "ARRAY")
{
$value = [$field->empty_value] if !@$value;
@rows = map { $self->value_to_rows($field, $_)->[0] } @$value;
}
elsif ($field->isa("EPrints::MetaField::Multipart"))
{
if( $field->isa( "EPrints::MetaField::Name" )) #need to deal with legacy phrase id's
{
my @bit_values;
foreach my $bit ( $field->get_input_bits() )
{
push @bit_values, $value->{$bit};
}
push @rows, \@bit_values;
}
else
{
push @rows, [map { $value->{$_->{sub_name}} } @{$field->property("fields_cache")}];
}
}
elsif ($field->isa("EPrints::MetaField::Compound"))
{
my @sub_values;
foreach my $key (keys %{$value})
{
push @sub_values, $value->{$key};
}
push @rows, \@sub_values;
}
else
{
push @rows, [$value];
}
return \@rows;
}
#used for custom exports that might return a field or an array (but aren't necesarily associated with a field!)
sub custom_value_to_rows
{
my ($self, $value) = @_;
my @rows;
if (ref($value) eq "ARRAY")
{
@rows = map { $self->custom_value_to_rows($_)->[0] } @$value;
}
else
{
push @rows, [$value];
}
return \@rows;
}
1;
=head1 COPYRIGHT
=for COPYRIGHT BEGIN
Copyright 2000-2011 University of Southampton.
=for COPYRIGHT END
=for LICENSE BEGIN
This file is part of EPrints L.
EPrints is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
EPrints is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with EPrints. If not, see L.
=for LICENSE END