Skip to content

Instantly share code, notes, and snippets.

@phluid61
Last active Sep 14, 2017
Embed
What would you like to do?
EPrints - custom view menu size function

Adds a custom function to EPrints' repository view configuration, so you can define a subroutine for each menu level that returns the map of {id=>count} for that level.

Particularly handy when the a conflict between the menu's fields and the generated DISTINCT BY clause include NULL values in the menu despite allow_null=>0 being specified in config.

See the discussion at http://mailman.ecs.soton.ac.uk/pipermail/eprints-tech/2017-September/006807.html

$c->{browse_views} = [
# ...
{
id => "person",
menus => [
{
fields => [ "creators_id", "editors_id" ],
new_column_at => [ 1, 1 ],
mode => "sections",
allow_null => 0,
open_first_section => 1,
group_range_function => "EPrints::Update::Views::cluster_ranges_30",
grouping_function => "EPrints::Update::Views::group_by_a_to_z",
# returns a HASHREF of { person_id=>count(eprintid), ... }
size_function => sub {
my( $repo, $filters ) = @_;
my $sql = "
SELECT `d`.`person_id`, COUNT(DISTINCT `d`.`eprintid`) FROM
(
SELECT `creators_id` AS `person_id`, `eprintid`
FROM `eprint_creators_id`
WHERE `creators_id` IS NOT NULL AND `creators_id` <> ''
UNION
SELECT `editors_id` AS `person_id`, `eprintid`
FROM `eprint_editors_id`
WHERE `editors_id` IS NOT NULL AND `editors_id` <> ''
) AS `d`
JOIN `eprint` ON `d`.`eprintid` = `eprint`.`eprintid`
WHERE `eprint`.`eprint_status` = 'archive'
AND `eprint`.`metadata_visibility` = 'show'
AND `eprint`.`replacedby` IS NULL
AND NOT EXISTS (SELECT 1 FROM `eprint` AS `e` WHERE `e`.`succeeds` = `eprint`.`eprintid`)
GROUP BY `person_id`";
my $sth = $repo->get_database->prepare( $sql );
$repo->get_database->execute( $sth, $sql );
my %results;
while( my @row = $sth->fetchrow_array )
{
my( $p, $n ) = @row;
$results{ $p } = $n;
}
$sth->finish;
return \%results;
},
},
],
order => "-date/title",
variations => [ "type", "date;truncate=4,reverse" ],
citation => "view",
max_menu_age => 7 * 24 * 60 * 60,
max_list_age => 7 * 24 * 60 * 60,
},
# ...
];
# ...
sub fieldlist_sizes
{
my( $self, $path_values, $menu_level, $filters ) = @_;
my $repo = $self->repository;
my $dataset = $self->dataset;
my $menus_fields = $self->menus_fields;
$filters = $self->get_filters( $path_values ) if !defined $filters;
my $menu_fields = $menus_fields->[$menu_level];
# if there are lower levels that require a value being set then we need to
# check that, otherwise we get the wrong counts at this level
for(my $i = @$path_values; $i < @$menus_fields; ++$i)
{
my $menu_fields = $menus_fields->[$i];
my $menu = $self->{menus}->[$i];
if( !$menu->{allow_null} )
{
push @$filters,
{ meta_fields => [map { $_->name } @$menu_fields], match => "SET" };
}
}
# get the id/counts for the menu level requested
my $id_map;
my $custom_func = $self->{menus}[$menu_level]->{size_function};
if( $custom_func )
{
$id_map = $self->call($custom_func, $repo, $filters);
}
else
{
my $searchexp = $dataset->prepare_search(
filters => $filters,
);
$id_map = $searchexp->perform_distinctby( $menu_fields );
}
# ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment