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

(-)a/Koha/REST/Plugin/Objects.pm (-1 / +5 lines)
Lines 97-102 sub register { Link Here
97
                }
97
                }
98
            }
98
            }
99
99
100
            if( defined $reserved_params->{q} ) {
101
                $filtered_params //={};
102
                $filtered_params = $c->merge_q_params( $filtered_params, $reserved_params->{q}, $result_set );
103
            }
100
            # Perform search
104
            # Perform search
101
            my $objects = $result_set->search( $filtered_params, $attributes );
105
            my $objects = $result_set->search( $filtered_params, $attributes );
102
106
Lines 106-112 sub register { Link Here
106
                    params => $args,
110
                    params => $args,
107
                });
111
                });
108
            }
112
            }
109
113
            
110
            return $objects->to_api({ embed => $embed });
114
            return $objects->to_api({ embed => $embed });
111
        }
115
        }
112
    );
116
    );
(-)a/Koha/REST/Plugin/Query.pm (-1 / +71 lines)
Lines 20-25 use Modern::Perl; Link Here
20
use Mojo::Base 'Mojolicious::Plugin';
20
use Mojo::Base 'Mojolicious::Plugin';
21
use List::MoreUtils qw(any);
21
use List::MoreUtils qw(any);
22
use Scalar::Util qw(reftype);
22
use Scalar::Util qw(reftype);
23
use JSON qw(decode_json);
23
24
24
use Koha::Exceptions;
25
use Koha::Exceptions;
25
26
Lines 179-184 is raised. Link Here
179
        }
180
        }
180
    );
181
    );
181
182
183
=head3 merge_q_params
184
185
    $c->merge_q_params( $filtered_params, $q_params, $result_set );
186
187
Merges parameters from $q_params into $filtered_params.
188
189
=cut
190
191
    $app->helper(
192
        'merge_q_params' => sub {
193
194
            my ( $c, $filtered_params, $q_params, $result_set ) = @_;
195
196
            $q_params = decode_json($q_params);
197
198
            my $params = _parse_dbic_query($q_params, $result_set);
199
200
            return $params unless scalar(keys %{$filtered_params});
201
            return {'-and' => [$params, $filtered_params ]};
202
        }
203
    );
204
182
=head3 stash_embed
205
=head3 stash_embed
183
206
184
    $c->stash_embed( $c->match->endpoint->pattern->defaults->{'openapi.op_spec'} );
207
    $c->stash_embed( $c->match->endpoint->pattern->defaults->{'openapi.op_spec'} );
Lines 229-235 is raised. Link Here
229
252
230
sub _reserved_words {
253
sub _reserved_words {
231
254
232
    my @reserved_words = qw( _match _order_by _page _per_page );
255
    my @reserved_words = qw( _match _order_by _page _per_page q );
233
    return \@reserved_words;
256
    return \@reserved_words;
234
}
257
}
235
258
Lines 340-343 sub _parse_prefetch { Link Here
340
    return $prefetch;
363
    return $prefetch;
341
}
364
}
342
365
366
sub _from_api_param {
367
    my ($key, $result_set) = @_;
368
369
    if($key =~ /\./) {
370
371
        my ($curr, $next) = split /\s*\.\s*/, $key, 2;
372
373
        my $ko_class = $result_set->prefetch_whitelist->{$curr};
374
375
        Koha::Exceptions::BadParameter->throw("Cannot find Koha::Object class for $curr")
376
            unless defined $ko_class;
377
378
        $result_set = $ko_class->new;
379
380
        if ($next =~ /\./) {
381
            return _from_api_param($next, $result_set);
382
        } else {
383
            return $curr.'.'.(defined $result_set->from_api_mapping ? $result_set->from_api_mapping->{$next}:$next);
384
        }
385
    } else {
386
        return defined $result_set->from_api_mapping->{$key} ? $result_set->from_api_mapping->{$key} : $key;
387
    }
388
}
389
390
sub _parse_dbic_query {
391
    my ($q_params, $result_set) = @_;
392
393
    if(reftype($q_params) && reftype($q_params) eq 'HASH') {
394
        my $parsed_hash;
395
        foreach my $key (keys %{$q_params}) {
396
            if($key =~ /-?(not_?)?bool/i ) {
397
                $parsed_hash->{$key} = _from_api_param($q_params->{$key}, $result_set);
398
                next;
399
            }
400
            my $k = _from_api_param($key, $result_set);
401
            $parsed_hash->{$k} = _parse_dbic_query($q_params->{$key}, $result_set);
402
        }
403
        return $parsed_hash;
404
    } elsif (reftype($q_params) && reftype($q_params) eq 'ARRAY') {
405
        my @mapped = map{ _parse_dbic_query($_, $result_set) } @$q_params;
406
        return \@mapped;
407
    } else {
408
        return $q_params;
409
    }
410
411
}
412
343
1;
413
1;
(-)a/t/Koha/REST/Plugin/Query.t (-1 / +46 lines)
Lines 23-28 use Try::Tiny; Link Here
23
23
24
use Koha::Cities;
24
use Koha::Cities;
25
use Koha::Holds;
25
use Koha::Holds;
26
use Koha::Biblios;
26
27
27
app->log->level('error');
28
app->log->level('error');
28
29
Lines 134-139 get '/dbic_merge_prefetch' => sub { Link Here
134
    $c->render( json => $attributes, status => 200 );
135
    $c->render( json => $attributes, status => 200 );
135
};
136
};
136
137
138
get '/merge_q_params' => sub {
139
  my $c = shift;
140
  my $filtered_params = {'biblio_id' => 1};
141
  my $result_set = Koha::Biblios->new;
142
143
  $filtered_params = $c->merge_q_params($filtered_params, $c->req->param('q'), $result_set);
144
145
  $c->render( json => $filtered_params, status => 200 );
146
};
147
137
get '/build_query' => sub {
148
get '/build_query' => sub {
138
    my $c = shift;
149
    my $c = shift;
139
    my ( $filtered_params, $reserved_params ) =
150
    my ( $filtered_params, $reserved_params ) =
Lines 208-214 sub to_model { Link Here
208
219
209
# The tests
220
# The tests
210
221
211
use Test::More tests => 5;
222
use Test::More tests => 6;
212
use Test::Mojo;
223
use Test::Mojo;
213
224
214
subtest 'extract_reserved_params() tests' => sub {
225
subtest 'extract_reserved_params() tests' => sub {
Lines 296-301 subtest '/dbic_merge_prefetch' => sub { Link Here
296
      ->json_like( '/prefetch/1' => qr/item|biblio/ );
307
      ->json_like( '/prefetch/1' => qr/item|biblio/ );
297
};
308
};
298
309
310
subtest '/merge_q_params' => sub {
311
  plan tests => 3;
312
  my $t = Test::Mojo->new;
313
314
  $t->get_ok('/merge_q_params?q={"-not_bool": "suggestions.suggester.patron_card_lost", "-or": [{"creation_date": {"!=": ["fff", "zzz", "xxx"]}},{"suggestions.suggester.housebound_profile.frequency": "123"}, {"suggestions.suggester.library_id": {"like": "%CPL%"}}]}')->status_is(200)
315
    ->json_is( '/-and' => [
316
        {
317
          "-not_bool" => "suggester.lost",
318
          "-or" => [
319
            {
320
              "datecreated" => {
321
                "!=" => [
322
                  "fff",
323
                  "zzz",
324
                  "xxx"
325
                ]
326
              }
327
            },
328
            {
329
              "housebound_profile.frequency" => 123
330
            },
331
            {
332
              "suggester.branchcode" => {
333
                "like" => "\%CPL\%"
334
              }
335
            }
336
          ]
337
        },
338
        {
339
          "biblio_id" => 1
340
        }
341
      ]);
342
};
343
299
subtest '_build_query_params_from_api' => sub {
344
subtest '_build_query_params_from_api' => sub {
300
345
301
    plan tests => 16;
346
    plan tests => 16;
(-)a/t/db_dependent/Koha/REST/Plugin/Objects.t (-2 / +41 lines)
Lines 20-25 use Modern::Perl; Link Here
20
use Koha::Acquisition::Orders;
20
use Koha::Acquisition::Orders;
21
use Koha::Cities;
21
use Koha::Cities;
22
use Koha::Holds;
22
use Koha::Holds;
23
use Koha::Biblios;
23
24
24
# Dummy app for testing the plugin
25
# Dummy app for testing the plugin
25
use Mojolicious::Lite;
26
use Mojolicious::Lite;
Lines 55-62 get '/patrons/:patron_id/holds' => sub { Link Here
55
    $c->render( status => 200, json => {count => scalar(@$holds)} );
56
    $c->render( status => 200, json => {count => scalar(@$holds)} );
56
};
57
};
57
58
59
get '/biblios' => sub {
60
    my $c = shift;
61
    $c->validation->output($c->req->params->to_hash);
62
    my $biblios_set = Koha::Biblios->new;
63
    $c->stash("koha.embed", {
64
        "suggestions" => {
65
            children => {
66
                "suggester" => {}
67
            }
68
        }
69
    });
70
    my $biblios = $c->objects->search($biblios_set);
71
    
72
    $c->render( status => 200, json => {count => scalar(@$biblios)} );
73
};
74
58
# The tests
75
# The tests
59
use Test::More tests => 4;
76
use Test::More tests => 5;
60
use Test::Mojo;
77
use Test::Mojo;
61
78
62
use t::lib::TestBuilder;
79
use t::lib::TestBuilder;
Lines 220-222 subtest 'objects.search helper, with path parameters and _match' => sub { Link Here
220
237
221
    $schema->storage->txn_rollback;
238
    $schema->storage->txn_rollback;
222
};
239
};
223
- 
240
241
subtest 'object.search helper with q parameter' => sub {
242
    plan tests => 4;
243
244
    $schema->storage->txn_begin;
245
246
    my $patron1 = $builder->build_object( { class => "Koha::Patrons" } );
247
    my $patron2 = $builder->build_object( { class => "Koha::Patrons" } );
248
    my $biblio1 = $builder->build_sample_biblio;
249
    my $biblio2 = $builder->build_sample_biblio;
250
    my $biblio3 = $builder->build_sample_biblio;
251
    my $suggestion1 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron1->borrowernumber, biblionumber => $biblio1->biblionumber} } );
252
    my $suggestion2 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio2->biblionumber} } );
253
    my $suggestion3 = $builder->build_object( { class => "Koha::Suggestions", value => { suggestedby => $patron2->borrowernumber, biblionumber => $biblio3->biblionumber} } );
254
255
    $t->get_ok('/biblios?q={"suggestions.suggester.patron_id": "'.$patron1->borrowernumber.'"}')
256
      ->json_is('/count' => 1, 'there should be 1 biblio with suggestions of patron 1');
257
258
    $t->get_ok('/biblios?q={"suggestions.suggester.patron_id": "'.$patron2->borrowernumber.'"}')
259
      ->json_is('/count' => 2, 'there should be 2 biblios with suggestions of patron 2');
260
261
    $schema->storage->txn_rollback;
262
}

Return to bug 24502