View | Details | Raw Unified | Return to bug 33974
Collapse All | Expand All

(-)a/Koha/REST/Plugin/Objects.pm (-16 / +52 lines)
Lines 112-121 shouldn't be called twice in it. Link Here
112
112
113
    $app->helper(
113
    $app->helper(
114
        'objects.search' => sub {
114
        'objects.search' => sub {
115
            my ( $c, $result_set ) = @_;
115
            my ( $c, $result_set, $query_fixers ) = @_;
116
116
117
            # Generate the resultset using the HTTP request information
117
            # Generate the resultset using the HTTP request information
118
            my $objects_rs = $c->objects->search_rs($result_set);
118
            my $objects_rs = $c->objects->search_rs( $result_set, $query_fixers );
119
119
120
            # Add pagination headers
120
            # Add pagination headers
121
            $c->add_pagination_headers();
121
            $c->add_pagination_headers();
Lines 127-139 shouldn't be called twice in it. Link Here
127
=head3 objects.search_rs
127
=head3 objects.search_rs
128
128
129
    my $patrons_object = Koha::Patrons->new;
129
    my $patrons_object = Koha::Patrons->new;
130
    my $patrons_rs = $c->objects->search_rs( $patrons_object );
130
    my $patrons_rs = $c->objects->search_rs( $patrons_object [, $query_fixers ] );
131
    . . .
131
    . . .
132
    return $c->render({ status => 200, openapi => $patrons_rs->to_api });
132
    return $c->render({ status => 200, openapi => $patrons_rs->to_api });
133
133
134
Returns the passed Koha::Objects resultset filtered as requested by the api query
134
Returns the passed Koha::Objects resultset filtered as requested by the api query
135
parameters and with requested embeds applied.
135
parameters and with requested embeds applied.
136
136
137
The optional I<$query_fixers> parameter is expected to be a reference to a list of
138
function references. This functions need to accept two parameters: ( $query, $no_quotes ).
139
140
The I<$query> is a string to be adapted. A modified version will be returned. The
141
I<$no_quotes> parameter controls if quotes need to be added for matching inside the string.
142
Quoting should be used by default, for replacing JSON keys e.g "biblio.isbn" would match
143
and biblio.isbn wouldn't.
144
137
Warning: this helper stashes base values for the pagination headers to the calling
145
Warning: this helper stashes base values for the pagination headers to the calling
138
controller, and thus shouldn't be called twice in it.
146
controller, and thus shouldn't be called twice in it.
139
147
Lines 141-155 controller, and thus shouldn't be called twice in it. Link Here
141
149
142
    $app->helper(
150
    $app->helper(
143
        'objects.search_rs' => sub {
151
        'objects.search_rs' => sub {
144
            my ( $c, $result_set ) = @_;
152
            my ( $c, $result_set, $query_fixers ) = @_;
145
153
146
            my $args       = $c->validation->output;
154
            my $args       = $c->validation->output;
147
            my $attributes = {};
155
            my $attributes = {};
148
156
157
            $query_fixers //= [];
158
149
            # Extract reserved params
159
            # Extract reserved params
150
            my ( $filtered_params, $reserved_params, $path_params ) =
160
            my ( $filtered_params, $reserved_params, $path_params ) =
151
              $c->extract_reserved_params($args);
161
              $c->extract_reserved_params($args);
152
162
163
            if ( exists $reserved_params->{_order_by} ) {
164
                # _order_by passed, fix if required
165
                for my $p ( @{$reserved_params->{_order_by}} ) {
166
                    foreach my $qf ( @{$query_fixers} ) {
167
                        $p = $qf->($p, 1); # 1 => no quotes on matching
168
                    }
169
                }
170
            }
171
153
            # Merge sorting into query attributes
172
            # Merge sorting into query attributes
154
            $c->dbic_merge_sorting(
173
            $c->dbic_merge_sorting(
155
                {
174
                {
Lines 204-234 controller, and thus shouldn't be called twice in it. Link Here
204
223
205
                my @query_params_array;
224
                my @query_params_array;
206
225
207
                # query in request body, JSON::Validator already decoded it
208
                push @query_params_array, $reserved_params->{query}
209
                  if defined $reserved_params->{query};
210
211
                my $json = JSON->new;
226
                my $json = JSON->new;
212
227
228
                # query in request body, JSON::Validator already decoded it
229
                if ( $reserved_params->{query} ) {
230
                    my $query = $json->encode( $reserved_params->{query} );
231
                    foreach my $qf ( @{$query_fixers} ) {
232
                        $query = $qf->($query);
233
                    }
234
                    push @query_params_array, $json->decode($query);
235
                }
236
213
                if ( ref( $reserved_params->{q} ) eq 'ARRAY' ) {
237
                if ( ref( $reserved_params->{q} ) eq 'ARRAY' ) {
214
238
215
                   # q is defined as multi => JSON::Validator generates an array
239
                   # q is defined as multi => JSON::Validator generates an array
216
                    foreach my $q ( @{ $reserved_params->{q} } ) {
240
                    foreach my $q ( @{ $reserved_params->{q} } ) {
217
                        push @query_params_array, $json->decode($q)
241
                        if ( $q ) { # skip if exists but is empty
218
                          if $q;    # skip if exists but is empty
242
                            foreach my $qf (@{$query_fixers}) {
243
                                $q = $qf->($q);
244
                            }
245
                            push @query_params_array, $json->decode($q);
246
                        }
219
                    }
247
                    }
220
                }
248
                }
221
                else {
249
                else {
222
                    # objects.search called outside OpenAPI context
250
                    # objects.search called outside OpenAPI context
223
                    # might be a hashref
251
                    # might be a hashref
224
                    push @query_params_array,
252
                    if ( $reserved_params->{q} ) {
225
                      $json->decode( $reserved_params->{q} )
253
                        my $q = $reserved_params->{q};
226
                      if $reserved_params->{q};
254
                        foreach my $qf (@{$query_fixers}) {
255
                            $q = $qf->($q);
256
                        }
257
                        push @query_params_array, $json->decode( $q );
258
                    }
227
                }
259
                }
228
260
229
                push @query_params_array,
261
                if ( $reserved_params->{'x-koha-query'} ) {
230
                  $json->decode( $reserved_params->{'x-koha-query'} )
262
                    my $q = $reserved_params->{'x-koha-query'};
231
                  if defined $reserved_params->{'x-koha-query'};
263
                    foreach my $qf (@{$query_fixers}) {
264
                        $q = $qf->($q);
265
                    }
266
                    push @query_params_array, $json->decode( $q );
267
                }
232
268
233
                my $query_params;
269
                my $query_params;
234
270
(-)a/Koha/REST/V1/Biblios.pm (-4 / +5 lines)
Lines 31-36 use C4::Context; Link Here
31
31
32
use Koha::Items;
32
use Koha::Items;
33
33
34
use Clone qw( clone );
34
use List::MoreUtils qw( any );
35
use List::MoreUtils qw( any );
35
use MARC::Record::MiJ;
36
use MARC::Record::MiJ;
36
37
Lines 797-808 Controller function that handles retrieving a single biblio object Link Here
797
sub list {
798
sub list {
798
    my $c = shift->openapi->valid_input or return;
799
    my $c = shift->openapi->valid_input or return;
799
800
800
    my $attributes;
801
    my @prefetch = qw(biblioitem);
801
    $attributes =
802
    push @prefetch, 'metadata'    # don't prefetch metadata if not needed
802
      { prefetch => ['metadata'] }    # don't prefetch metadata if not needed
803
      unless $c->req->headers->accept =~ m/application\/json/;
803
      unless $c->req->headers->accept =~ m/application\/json/;
804
804
805
    my $biblios = $c->objects->search_rs( Koha::Biblios->new );
805
    my $rs = Koha::Biblios->search( undef, { prefetch => \@prefetch });
806
    my $biblios = $c->objects->search_rs( $rs, [(sub{ $rs->api_query_fixer( $_[0], '', $_[1] ) })] );
806
807
807
    return try {
808
    return try {
808
809
(-)a/t/db_dependent/api/v1/biblios.t (-5 / +16 lines)
Lines 36-41 use Koha::Database; Link Here
36
use Koha::Checkouts;
36
use Koha::Checkouts;
37
use Koha::Old::Checkouts;
37
use Koha::Old::Checkouts;
38
38
39
use Mojo::JSON qw(encode_json);
40
39
my $schema  = Koha::Database->new->schema;
41
my $schema  = Koha::Database->new->schema;
40
my $builder = t::lib::TestBuilder->new;
42
my $builder = t::lib::TestBuilder->new;
41
43
Lines 1617-1623 subtest 'put() tests' => sub { Link Here
1617
1619
1618
subtest 'list() tests' => sub {
1620
subtest 'list() tests' => sub {
1619
1621
1620
    plan tests => 15;
1622
    plan tests => 17;
1621
1623
1622
    $schema->storage->txn_begin;
1624
    $schema->storage->txn_begin;
1623
1625
Lines 1651-1658 subtest 'list() tests' => sub { Link Here
1651
    t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
1653
    t::lib::Mocks::mock_preference('marcflavour', 'MARC21');
1652
    my $biblionumber2 = $builder->build_sample_biblio->biblionumber;
1654
    my $biblionumber2 = $builder->build_sample_biblio->biblionumber;
1653
1655
1654
    my $search =
1656
    my $search = encode_json( [ { 'me.biblio_id' => $biblionumber1 }, { 'me.biblio_id' => $biblionumber2 } ] );
1655
"[{\"biblionumber\": \"$biblionumber1\"}, {\"biblionumber\": \"$biblionumber2\"}]";
1656
    $t->get_ok(
1657
    $t->get_ok(
1657
        "//$userid:$password@/api/v1/biblios/" => { 'x-koha-query' => $search }
1658
        "//$userid:$password@/api/v1/biblios/" => { 'x-koha-query' => $search }
1658
    )->status_is(403);
1659
    )->status_is(403);
Lines 1686-1691 subtest 'list() tests' => sub { Link Here
1686
          { Accept => 'text/plain', 'x-koha-query' => $search } )
1687
          { Accept => 'text/plain', 'x-koha-query' => $search } )
1687
      ->status_is(200);
1688
      ->status_is(200);
1688
1689
1690
    # DELETE any biblio with ISBN = TOMAS
1691
    Koha::Biblios->search({ 'biblioitem.isbn' => 'TOMAS' }, { join => [ 'biblioitem' ] })
1692
                 ->delete;
1693
1694
1695
    my $isbn_query = encode_json({ isbn => 'TOMAS' });
1696
    $biblio->biblioitem->set({ isbn => 'TOMAS' })->store;
1697
    $t->get_ok( "//$userid:$password@/api/v1/biblios?q=$isbn_query" =>
1698
          { Accept => 'text/plain' } )
1699
      ->status_is(200);
1700
1689
    $schema->storage->txn_rollback;
1701
    $schema->storage->txn_rollback;
1690
};
1702
};
1691
1703
Lines 1801-1804 subtest 'update_item() tests' => sub { Link Here
1801
    ->json_is('/replacement_price', 30);
1813
    ->json_is('/replacement_price', 30);
1802
1814
1803
  $schema->storage->txn_rollback;
1815
  $schema->storage->txn_rollback;
1804
};
1816
};
1805
- 

Return to bug 33974