LP#1549505: fix badge scoping
authorGalen Charlton <gmc@esilibrary.com>
Fri, 25 Mar 2016 16:16:50 +0000 (12:16 -0400)
committerGalen Charlton <gmc@esilibrary.com>
Fri, 25 Mar 2016 16:16:50 +0000 (12:16 -0400)
This patch fixes badge scoping during searches
so that only badges at the search location and its
ancestors are used to calculate popularity. Note that
if a user explicitly puts in a badge_orgs search "filter"
in the query, that will override this default behavior,
allowing you to do things like search the entire consortium,
but bring hits that are most popular per a badge
scoped at branch X to the top.

Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/metabib.pm

index af76ccc..b480e73 100644 (file)
@@ -848,7 +848,7 @@ sub toSQL {
     my $borgs = '';
     my ($bo_filter) = $self->find_filter('badge_orgs');
     if ($bo_filter && @{$bo_filter->args}) {
-        my $borgs = join (',', grep /^\d+$/, @{$bo_filter->args});
+        $borgs = join (',', grep /^\d+$/, @{$bo_filter->args});
     }
 
     # Build the badge-ish WITH query
index 00108b3..debc865 100644 (file)
@@ -3164,63 +3164,52 @@ sub query_parser_fts_wrapper {
 
 
     my $borgs = undef;
-    my $site = undef;
+    if (!$base_plan->parse_tree->find_filter('badge_orgs')) {
+        # supply a suitable badge_orgs filter unless user has
+        # explicitly supplied one
+        my $site = undef;
 
-    my @lg_id_list = @{$args{location_groups}} if (ref $args{location_groups});
+        my @lg_id_list = @{$args{location_groups}} if (ref $args{location_groups});
 
-    my ($lg_filter) = $base_plan->parse_tree->find_filter('location_groups');
-    @lg_id_list = @{$lg_filter->args} if ($lg_filter && @{$lg_filter->args});
+        my ($lg_filter) = $base_plan->parse_tree->find_filter('location_groups');
+        @lg_id_list = @{$lg_filter->args} if ($lg_filter && @{$lg_filter->args});
 
-    if (@lg_id_list) {
-        my @borg_list;
-        for my $lg ( grep { /^\d+$/ } @lg_id_list ) {
-            my $lg_obj = asset::copy_location_group->retrieve($lg);
-            next unless $lg_obj;
-
-            if (''.$lg_obj->owner == $top_org->id) {
-                $borgs = undef;
-                last;
-            }
-
-            push(@borg_list, ''.$lg_obj->owner);
-        }
-        $borgs = join(',', @borg_list) if @borg_list;
-    }
-
-    if (!$borgs) {
-        my ($site_filter) = $base_plan->parse_tree->find_filter('site');
-        if ($site_filter && @{$site_filter->args}) {
-            $site = $top_org if ($site_filter->args->[0] eq '-');
-            $site = $top_org if ($site_filter->args->[0] eq $top_org->shortname);
-            $site = actor::org_unit->search( { shortname => $site_filter->args->[0] })->next unless ($site);
+        if (@lg_id_list) {
+            my @borg_list;
+            for my $lg ( grep { /^\d+$/ } @lg_id_list ) {
+                my $lg_obj = asset::copy_location_group->retrieve($lg);
+                next unless $lg_obj;
     
-        } elsif ($args{org_unit}) {
-            $site = $top_org if ($args{org_unit} eq '-');
-            $site = $top_org if ($args{org_unit} eq $top_org->shortname);
-            $site = actor::org_unit->search( { shortname => $args{org_unit} })->next unless ($site);
+                push(@borg_list, ''.$lg_obj->owner);
+            }
+            $borgs = join(',', @borg_list) if @borg_list;
         }
     
-        if ($site && $site->id != $top_org->id) {
-            my ($depth_filter) = $base_plan->parse_tree->find_filter('depth');
-            my $depth = $depth_filter->args->[0] if ($depth_filter && $depth_filter->args->[0] =~ /^\d+$/);
-            $depth = $args{depth} if (!defined($depth) && defined($args{depth}) && $args{depth} =~ /^\d+$/);
-    
-            if (defined $depth and $depth > 0) { # Not scoped to the top of the tree
-                $borgs = OpenSRF::AppSession->create( 'open-ils.cstore' )->request(
-                    'open-ils.cstore.json_query.atomic',
-                    { from => [ 'actor.org_unit_descendants', $site->id, $depth ] }
-                )->gather(1);
+        if (!$borgs) {
+            my ($site_filter) = $base_plan->parse_tree->find_filter('site');
+            if ($site_filter && @{$site_filter->args}) {
+                $site = $top_org if ($site_filter->args->[0] eq '-');
+                $site = $top_org if ($site_filter->args->[0] eq $top_org->shortname);
+                $site = actor::org_unit->search( { shortname => $site_filter->args->[0] })->next unless ($site);
+            } elsif ($args{org_unit}) {
+                $site = $top_org if ($args{org_unit} eq '-');
+                $site = $top_org if ($args{org_unit} eq $top_org->shortname);
+                $site = actor::org_unit->search( { shortname => $args{org_unit} })->next unless ($site);
             } else {
+                $site = $top_org;
+            }
+
+            if ($site) {
                 $borgs = OpenSRF::AppSession->create( 'open-ils.cstore' )->request(
                     'open-ils.cstore.json_query.atomic',
-                    { from => [ 'actor.org_unit_descendants', $site->id ] }
+                    { from => [ 'actor.org_unit_ancestors', $site->id ] }
                 )->gather(1);
-            }
-    
-            if (ref $borgs && @$borgs) {
-                $borgs = join(',', map { $_->{'actor.org_unit_descendants'} } @$borgs);
-            } else {
-                $borgs = undef;
+
+                if (ref $borgs && @$borgs) {
+                    $borgs = join(',', map { $_->{'id'} } @$borgs);
+                } else {
+                    $borgs = undef;
+                }
             }
         }
     }