Bugzilla – Attachment 159652 Details for
Bug 30645
Generated DBIC query incorrect for API searches across joined extended attributes when several terms are passed
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 30645: Consider multiple instances of extended_attributes in query params
Bug-30645-Consider-multiple-instances-of-extendeda.patch (text/plain), 9.28 KB, created by
Pedro Amorim
on 2023-12-07 14:52:17 UTC
(
hide
)
Description:
Bug 30645: Consider multiple instances of extended_attributes in query params
Filename:
MIME Type:
Creator:
Pedro Amorim
Created:
2023-12-07 14:52:17 UTC
Size:
9.28 KB
patch
obsolete
>From 8a9d19c406157cdda5a7043d66029723da256355 Mon Sep 17 00:00:00 2001 >From: Pedro Amorim <pedro.amorim@ptfs-europe.com> >Date: Thu, 30 Nov 2023 15:43:02 -0100 >Subject: [PATCH] Bug 30645: Consider multiple instances of extended_attributes > in query params > >This will rewrite a query like: > >{ > "-and":[ > [ > { > "extended_attributes.value":{ > "like":"abc%" > }, > "extended_attributes.code":[ > [ > "arbitrary_attr_code", > "another_attr_code" > ] > ] > } > ], > [ > { > "extended_attributes.value":{ > "like":"123%" > }, > "extended_attributes.code":[ > [ > "arbitrary_attr_code", > "another_attr_code" > ] > ] > } > ] > ] >} > >To: > >{ > "-and":[ > [ > { > "extended_attributes.value":{ > "like":"abc%" > }, > "extended_attributes.code":[ > [ > "arbitrary_attr_code", > "another_attr_code" > ] > ] > } > ], > [ > { > "extended_attributes_2.value":{ > "like":"123%" > }, > "extended_attributes_2.code":[ > [ > "arbitrary_attr_code", > "another_attr_code" > ] > ] > } > ] > ] >} > >And it'll also add the number of required 'join' attributes to the query >attributes to match it. > >Test plan (with Joubu's test patch applied), run: >prove t/db_dependent/selenium/patrons_search.t > >Or > >Test plan, k-t-d: >1) Create 2 patron attributes, visit: >/cgi-bin/koha/admin/patron-attr-types.pl >2) Name the first attribute 'test1' and the second attribute 'test2' >3) On both, tick the 'Searchable' and 'Search by default' checkboxes >4) Edit a koha borrower, example visit: >/cgi-bin/koha/members/memberentry.pl?op=modify&destination=circ&borrowernumber=51 >5) Put '123' on the test1 attribute, and 'abc' on the test2 attribute >6) Visit the main patrons page: >/cgi-bin/koha/members/members-home.pl >7) On the first left side filter input called 'Search', type '123' and search. Notice you get the patron result >8) Repeat step 7, but type 'abc' instead of '123'. Notice you get the patron result >9) Now do the same search but type '123 abc'. Notice you do not get the patron result. >10) Apply patch. Repeat test plan. Notice you get the patron result in step 9). >--- > Koha/REST/Plugin/Objects.pm | 8 ++ > Koha/REST/Plugin/Query.pm | 152 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 160 insertions(+) > >diff --git a/Koha/REST/Plugin/Objects.pm b/Koha/REST/Plugin/Objects.pm >index 32dab06d4b..7f06582b4d 100644 >--- a/Koha/REST/Plugin/Objects.pm >+++ b/Koha/REST/Plugin/Objects.pm >@@ -287,6 +287,14 @@ controller, and thus shouldn't be called twice in it. > $c->stash('koha.pagination.base_total' => $result_set->count); > $c->stash('koha.pagination.query_params' => $args); > >+ # Check and handle related metadata table joins >+ $c->dbic_extended_attributes_join( >+ { >+ attributes => $attributes, >+ filtered_params => $filtered_params >+ } >+ ); >+ > # Generate the resultset > my $objects_rs = $result_set->search( $filtered_params, $attributes ); > # Stash the page total if requires, total otherwise >diff --git a/Koha/REST/Plugin/Query.pm b/Koha/REST/Plugin/Query.pm >index 7aa092fae2..53decc94bc 100644 >--- a/Koha/REST/Plugin/Query.pm >+++ b/Koha/REST/Plugin/Query.pm >@@ -159,6 +159,34 @@ Generates the DBIC prefetch attribute based on embedded relations, and merges in > } > ); > >+=head3 dbic_extended_attributes_join >+ >+ $attributes = $c->dbic_extended_attributes_join({ attributes => $attributes, result_set => $result_set }); >+ >+Generates the DBIC join attribute based on extended_attributes query entries, and merges into I<$attributes>. >+ >+=cut >+ >+ $app->helper( >+ 'dbic_extended_attributes_join' => sub { >+ my ( $c, $args ) = @_; >+ >+ my $attributes = $args->{attributes}; >+ my $filtered_params = $args->{filtered_params}; >+ >+ if ( reftype( $attributes->{prefetch} ) >+ && reftype( $attributes->{prefetch} ) eq 'ARRAY' >+ && grep ( /extended_attributes/, @{ $attributes->{prefetch} } ) ) >+ { >+ my $ea_entries = $self->_get_extended_attributes_entries( $filtered_params, 0 ); >+ while ( $ea_entries > 0 ) { >+ push( @{ $attributes->{join} }, 'extended_attributes' ); >+ $ea_entries--; >+ } >+ } >+ } >+ ); >+ > =head3 _build_query_params_from_api > > my $params = _build_query_params_from_api( $filtered_params, $reserved_params ); >@@ -486,7 +514,131 @@ sub _parse_dbic_query { > } else { > return $q_params; > } >+} >+ >+=head3 _get_extended_attributes_entries >+ >+ $self->_get_extended_attributes_entries( $filtered_params, 0 ) >+ >+Recursive function that returns the number of extended_attributes entries present in a query. >+Example: Returns 2 if given a $filtered_params containing the below: >+ >+{ >+ "-and":[ >+ [ >+ { >+ "extended_attributes.value":{ >+ "like":"abc%" >+ }, >+ "extended_attributes.code":[ >+ [ >+ "arbitrary_attr_code", >+ "another_attr_code" >+ ] >+ ] >+ } >+ ], >+ [ >+ { >+ "extended_attributes.value":{ >+ "like":"123%" >+ }, >+ "extended_attributes.code":[ >+ [ >+ "arbitrary_attr_code", >+ "another_attr_code" >+ ] >+ ] >+ } >+ ] >+ ] >+} >+ >+=cut >+ >+sub _get_extended_attributes_entries { >+ my ( $self, $params, $extended_attributes_entries ) = @_; >+ >+ if ( reftype($params) && reftype($params) eq 'HASH' ) { >+ >+ # rewrite additional_field_values table query params >+ $extended_attributes_entries = >+ _rewrite_related_metadata_query( $params, $extended_attributes_entries, 'field_id', 'value' ) >+ if $params->{'extended_attributes.field_id'}; >+ >+ # rewrite borrower_attributes table query params >+ $extended_attributes_entries = >+ _rewrite_related_metadata_query( $params, $extended_attributes_entries, 'code', 'attribute' ) >+ if $params->{'extended_attributes.code'}; >+ >+ # rewrite illrequestattributes table query params >+ $extended_attributes_entries = >+ _rewrite_related_metadata_query( $params, $extended_attributes_entries, 'type', 'value' ) >+ if $params->{'extended_attributes.type'}; >+ >+ foreach my $key ( keys %{$params} ) { >+ return $self->_get_extended_attributes_entries( $params->{$key}, $extended_attributes_entries ); >+ } >+ } elsif ( reftype($params) && reftype($params) eq 'ARRAY' ) { >+ foreach my $ea_instance (@$params) { >+ $extended_attributes_entries = >+ +$self->_get_extended_attributes_entries( $ea_instance, $extended_attributes_entries ); >+ } >+ return $extended_attributes_entries; >+ } else { >+ return $extended_attributes_entries; >+ } >+} >+ >+=head3 _rewrite_related_metadata_query >+ >+ $extended_attributes_entries = >+ _rewrite_related_metadata_query( $params, $extended_attributes_entries, 'field_id', 'value' ) >+ >+Helper function that rewrites all subsequent extended_attributes queries to match the alias generated by the dbic self left join >+Take the below example (patrons), assuming it is the third instance of an extended_attributes query: >+{ >+ "extended_attributes.value":{ >+ "like":"123%" >+ }, >+ "extended_attributes.code":[ >+ [ >+ "arbitrary_attr_code", >+ "another_attr_code" >+ ] >+ ] >+} >+ >+It'll be rewritten as: >+{ >+ "extended_attributes_3.value":{ >+ "like":"123%" >+ }, >+ "extended_attributes_3.code":[ >+ [ >+ "arbitrary_attr_code", >+ "another_attr_code" >+ ] >+ ] >+} >+ >+=cut >+ >+sub _rewrite_related_metadata_query { >+ my ( $params, $extended_attributes_entries, $key, $value ) = @_; >+ >+ $extended_attributes_entries++; >+ if ( $extended_attributes_entries > 1 ) { >+ my $old_key_value = delete $params->{ 'extended_attributes.' . $key }; >+ my $new_key_value = "extended_attributes_$extended_attributes_entries" . "." . $key; >+ $params->{$new_key_value} = $old_key_value; >+ >+ my $old_value_value = delete $params->{ 'extended_attributes.' . $value }; >+ my $new_value_value = "extended_attributes_$extended_attributes_entries" . "." . $value; >+ $params->{$new_value_value} = $old_value_value; >+ } > >+ return $extended_attributes_entries; > } > > 1; >-- >2.30.2
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 30645
:
134253
|
154949
|
159414
|
159450
|
159651
|
159652
|
159675
|
159676
|
160208
|
160216
|
161495
|
161528
|
164982
|
165009
|
165010
|
165011