From e98fde95a204fa55fbf3bcabcabadc9b20b838ad Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Wed, 4 Oct 2017 15:41:35 -0300 Subject: [PATCH] Bug 19410: Add Koha::Objects->search_for_api Following the discussion about the best way to make things simpler for developing the REST api, I quote Lari's email: "As many other endpoint will have the exact same usage, by looking at your example, I would prefer to avoid writing parameter / pagination / sorting / header handling for each list operation in our API controllers. Do you think it's possible to centralize all of this e.g. by passing $c into a customized search sub? Perhaps in Koha::Objects? so instead we could have something like (ignore my bad choice of naming)...: sub list_vendors { my $c = shift->openapi->valid_input or return; my $args = $c->validation->output; my $vendors; return try { $vendors = Koha::Acquisition::Booksellers->api_list_search($c); return $c->render(status => 200, openapi => $vendors); } catch { ... } }" We all agreed we neeed something like that. Here's a possible implementation. I take advantage of the previously written Mojo helpers, that are fully covered by tests. I submit this early so anyone can take a look and gather ideas to make it even better. I'm already using it (effectively) for the /acquisitions/orders endpoint I'm writing on bug 18731. Thanks! Signed-off-by: Tomas Cohen Arazi --- Koha/Objects.pm | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/Koha/Objects.pm b/Koha/Objects.pm index 8c79afda1a..d882e4b3a5 100644 --- a/Koha/Objects.pm +++ b/Koha/Objects.pm @@ -23,6 +23,7 @@ use Carp; use List::MoreUtils qw( none ); use Koha::Database; +use Koha::Exceptions; =head1 NAME @@ -170,6 +171,88 @@ sub search_related { } } +=head3 search_for_api + + my @objects = Koha::Objects->earch_for_api( $c ); + +Searches for objects given a controller object I<$c>. + +=cut + +sub search_for_api { + my ( $self, $c ) = @_; + + my $args = $c->validation->output; + my $attributes; + + # Extract reserved params + my ( $filtered_params, $reserved_params ) = $c->extract_reserved_params($args); + + # Merge sorting into query attributes + $c->dbic_merge_sorting( + { + attributes => $attributes, + params => $reserved_params + } + ); + + # Merge pagination into query attributes + $c->dbic_merge_pagination( + { + attributes => $attributes, + params => $reserved_params + } + ); + + # Perform search + my $objects = $self->search( $filtered_params, $attributes ); + $c->add_pagination_headers({ total => $objects->count, params => $args }) + if $objects->is_paged; + + return $objects; +} + +=head2 _build_query_params_from_api + + my $params = _build_query_params_from_api( $filtered_params, $reserved_params ); + +Builds the params for searching on DBIC based on the selected matching algorithm. +Valid options are I, I, I and I. Default is +I. If other value is passed, a Koha::Exceptions::WrongParameter exception +is raised. + +=cut + +sub _build_query_params_from_api { + + my ( $filtered_params, $reserved_params ) = @_; + + my $params; + my $match = $reserved_params->{_match} // 'contains'; + + foreach my $param ( keys %{$filtered_params} ) { + if ( $match eq 'contains' ) { + $params->{$param} = + { like => '%' . $filtered_params->{$param} . '%' }; + } + elsif ( $match eq 'starts_with' ) { + $params->{$param} = { like => $filtered_params->{$param} . '%' }; + } + elsif ( $match eq 'ends_with' ) { + $params->{$param} = { like => '%' . $filtered_params->{$param} }; + } + elsif ( $match eq 'exact' ) { + $params->{$param} = $filtered_params->{$param}; + } + else { + Koha::Exceptions::WrongParameter->throw( + "Invalid value for _match param ($match)"); + } + } + + return $params; +} + =head3 single my $object = Koha::Objects->search({}, { rows => 1 })->single -- 2.14.1