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

(-)a/Koha/REST/Plugin/Objects.pm (-22 / +104 lines)
Lines 49-54 the requested object. It passes through any embeds if specified. Link Here
49
    $app->helper(
49
    $app->helper(
50
        'objects.find' => sub {
50
        'objects.find' => sub {
51
            my ( $c, $result_set, $id ) = @_;
51
            my ( $c, $result_set, $id ) = @_;
52
            my $object = $c->objects->find_rs( $result_set, $id );
53
            return unless $object;
54
            return $c->objects->to_api($object);
55
        }
56
    );
57
58
=head3 objects.find_rs
59
60
    my $patrons_rs = Koha::Patrons->new;
61
    my $patrons = $c->objects->find_rs( $patrons_rs, $id );
62
63
Performs a database search using given Koha::Objects object and the $id.
64
65
Returns a new resultset for further processing. It passes through any embeds if specified.
66
67
=cut
68
69
    $app->helper(
70
        'objects.find_rs' => sub {
71
            my ( $c, $result_set, $id ) = @_;
52
72
53
            my $attributes = {};
73
            my $attributes = {};
54
74
Lines 66-74 the requested object. It passes through any embeds if specified. Link Here
66
86
67
            my $object = $result_set->find( $id, $attributes );
87
            my $object = $result_set->find( $id, $attributes );
68
88
69
            return unless $object;
89
            return $object;
70
71
            return $object->to_api({ embed => $embed, strings => $strings });
72
        }
90
        }
73
    );
91
    );
74
92
Lines 91-106 shouldn't be called twice in it. Link Here
91
        'objects.search' => sub {
109
        'objects.search' => sub {
92
            my ( $c, $result_set ) = @_;
110
            my ( $c, $result_set ) = @_;
93
111
94
            my $args = $c->validation->output;
112
            return $c->objects->to_api( $c->objects->search_rs($result_set) );
113
        }
114
    );
115
116
=head3 objects.search_rs
117
118
    my $patrons_rs = Koha::Patrons->new;
119
    my $filtered_patrons_rs = $c->objects->search_rs( $patrons_rs );
120
121
Performs a database search using given Koha::Objects object and query parameters.
122
123
Returns a new resultset for further processing.
124
125
Warning: this helper adds pagination headers to the calling controller, and thus
126
shouldn't be called twice in it.
127
128
=cut
129
130
    $app->helper(
131
        'objects.search_rs' => sub {
132
            my ( $c, $result_set ) = @_;
133
134
            my $args       = $c->validation->output;
95
            my $attributes = {};
135
            my $attributes = {};
96
136
97
            # Extract reserved params
137
            # Extract reserved params
98
            my ( $filtered_params, $reserved_params, $path_params ) = $c->extract_reserved_params($args);
138
            my ( $filtered_params, $reserved_params, $path_params ) =
139
              $c->extract_reserved_params($args);
140
99
            # Privileged reques?
141
            # Privileged reques?
100
            my $is_public = $c->stash('is_public');
142
            my $is_public = $c->stash('is_public');
101
            # Look for embeds
102
            my $embed   = $c->stash('koha.embed');
103
            my $strings = $c->stash('koha.strings');
104
143
105
            # Merge sorting into query attributes
144
            # Merge sorting into query attributes
106
            $c->dbic_merge_sorting(
145
            $c->dbic_merge_sorting(
Lines 112-121 shouldn't be called twice in it. Link Here
112
            );
151
            );
113
152
114
            # If no pagination parameters are passed, default
153
            # If no pagination parameters are passed, default
115
            $reserved_params->{_per_page} //= C4::Context->preference('RESTdefaultPageSize');
154
            $reserved_params->{_per_page} //=
116
            $reserved_params->{_page}     //= 1;
155
              C4::Context->preference('RESTdefaultPageSize');
156
            $reserved_params->{_page} //= 1;
117
157
118
            unless ( $reserved_params->{_per_page} == -1 ) {
158
            unless ( $reserved_params->{_per_page} == -1 ) {
159
119
                # Merge pagination into query attributes
160
                # Merge pagination into query attributes
120
                $c->dbic_merge_pagination(
161
                $c->dbic_merge_pagination(
121
                    {
162
                    {
Lines 137-144 shouldn't be called twice in it. Link Here
137
            if ( defined $filtered_params ) {
178
            if ( defined $filtered_params ) {
138
179
139
                # Apply the mapping function to the passed params
180
                # Apply the mapping function to the passed params
140
                $filtered_params = $result_set->attributes_from_api($filtered_params);
181
                $filtered_params =
141
                $filtered_params = $c->build_query_params( $filtered_params, $reserved_params );
182
                  $result_set->attributes_from_api($filtered_params);
183
                $filtered_params =
184
                  $c->build_query_params( $filtered_params, $reserved_params );
142
            }
185
            }
143
186
144
            if (   defined $reserved_params->{q}
187
            if (   defined $reserved_params->{q}
Lines 155-172 shouldn't be called twice in it. Link Here
155
198
156
                my $json = JSON->new;
199
                my $json = JSON->new;
157
200
158
                if ( ref($reserved_params->{q}) eq 'ARRAY' ) {
201
                if ( ref( $reserved_params->{q} ) eq 'ARRAY' ) {
159
                    # q is defined as multi => JSON::Validator generates an array
202
203
                   # q is defined as multi => JSON::Validator generates an array
160
                    foreach my $q ( @{ $reserved_params->{q} } ) {
204
                    foreach my $q ( @{ $reserved_params->{q} } ) {
161
                        push @query_params_array, $json->decode($q)
205
                        push @query_params_array, $json->decode($q)
162
                        if $q; # skip if exists but is empty
206
                          if $q;    # skip if exists but is empty
163
                    }
207
                    }
164
                }
208
                }
165
                else {
209
                else {
166
                    # objects.search called outside OpenAPI context
210
                    # objects.search called outside OpenAPI context
167
                    # might be a hashref
211
                    # might be a hashref
168
                    push @query_params_array, $json->decode($reserved_params->{q})
212
                    push @query_params_array,
169
                        if $reserved_params->{q};
213
                      $json->decode( $reserved_params->{q} )
214
                      if $reserved_params->{q};
170
                }
215
                }
171
216
172
                push @query_params_array,
217
                push @query_params_array,
Lines 182-197 shouldn't be called twice in it. Link Here
182
                    $query_params = $query_params_array[0];
227
                    $query_params = $query_params_array[0];
183
                }
228
                }
184
229
185
                $filtered_params = $c->merge_q_params( $filtered_params, $query_params, $result_set );
230
                $filtered_params =
231
                  $c->merge_q_params( $filtered_params, $query_params,
232
                    $result_set );
186
            }
233
            }
187
234
188
            # request sequence id (i.e. 'draw' Datatables parameter)
235
            # request sequence id (i.e. 'draw' Datatables parameter)
189
            $c->res->headers->add( 'x-koha-request-id' => $reserved_params->{'x-koha-request-id'} )
236
            $c->res->headers->add(
237
                'x-koha-request-id' => $reserved_params->{'x-koha-request-id'} )
190
              if $reserved_params->{'x-koha-request-id'};
238
              if $reserved_params->{'x-koha-request-id'};
191
239
192
            # If search_limited exists, use it
240
            # If search_limited exists, use it
193
            $result_set = $result_set->search_limited,
241
            $result_set = $result_set->search_limited,
194
                if $result_set->can('search_limited');
242
              if $result_set->can('search_limited');
195
243
196
            # Perform search
244
            # Perform search
197
            my $objects = $result_set->search( $filtered_params, $attributes );
245
            my $objects = $result_set->search( $filtered_params, $attributes );
Lines 199-211 shouldn't be called twice in it. Link Here
199
247
200
            $c->add_pagination_headers(
248
            $c->add_pagination_headers(
201
                {
249
                {
202
                    total      => ($objects->is_paged ? $objects->pager->total_entries : $objects->count),
250
                    total => (
251
                          $objects->is_paged
252
                        ? $objects->pager->total_entries
253
                        : $objects->count
254
                    ),
203
                    base_total => $total,
255
                    base_total => $total,
204
                    params     => $args,
256
                    params     => $args,
205
                }
257
                }
206
            );
258
            );
207
259
208
            return $objects->to_api({ embed => $embed, public => $is_public, strings => $strings });
260
            return $objects;
261
        }
262
    );
263
264
=head3 objects.to_api
265
266
    my $patrons_rs = Koha::Patrons->new;
267
    my $api_representation = $c->objects->to_api( $patrons_rs );
268
269
Returns the API representation of the passed resultset.
270
271
=cut
272
273
    $app->helper(
274
        'objects.to_api' => sub {
275
            my ( $c, $object ) = @_;
276
277
            # Privileged request?
278
            my $public = $c->stash('is_public');
279
280
            # Look for embeds
281
            my $embed   = $c->stash('koha.embed');
282
            my $strings = $c->stash('koha.strings');
283
284
            return $object->to_api(
285
                {
286
                    embed   => $embed,
287
                    public  => $public,
288
                    strings => $strings
289
                }
290
            );
209
        }
291
        }
210
    );
292
    );
211
}
293
}
(-)a/t/db_dependent/Koha/REST/Plugin/Objects.t (-2 / +110 lines)
Lines 43-48 get '/cities' => sub { Link Here
43
    $c->render( status => 200, json => $cities );
43
    $c->render( status => 200, json => $cities );
44
};
44
};
45
45
46
get '/cities/rs' => sub {
47
    my $c = shift;
48
    $c->validation->output( $c->req->params->to_hash );
49
    $c->stash_embed;
50
    my $cities = $c->objects->search_rs( Koha::Cities->new );
51
52
    $c->render( status => 200, json => { count => $cities->count } );
53
};
54
46
get '/cities/:city_id' => sub {
55
get '/cities/:city_id' => sub {
47
    my $c = shift;
56
    my $c = shift;
48
    my $id = $c->stash("city_id");
57
    my $id = $c->stash("city_id");
Lines 120-127 get '/my_patrons' => sub { Link Here
120
    );
129
    );
121
};
130
};
122
131
132
get '/cities/:city_id/rs' => sub {
133
    my $c = shift;
134
    $c->validation->output( $c->req->params->to_hash );
135
    $c->stash_embed;
136
    my $city_id = $c->param('city_id');
137
    my $city    = $c->objects->find_rs( Koha::Cities->new, $city_id );
138
139
    $c->render( status => 200, json => { name => $city->city_name } );
140
};
141
123
# The tests
142
# The tests
124
use Test::More tests => 16;
143
use Test::More tests => 18;
125
use Test::Mojo;
144
use Test::Mojo;
126
145
127
use t::lib::Mocks;
146
use t::lib::Mocks;
Lines 508-513 subtest 'objects.search helper order by embedded columns' => sub { Link Here
508
    $schema->storage->txn_rollback;
527
    $schema->storage->txn_rollback;
509
};
528
};
510
529
530
subtest 'objects.search_rs helper' => sub {
531
    plan tests => 3;
532
533
    $schema->storage->txn_begin;
534
535
    # Remove existing cities to have more control on the search results
536
    Koha::Cities->delete;
537
538
 # Create three sample cities that match the query. This makes sure we
539
 # always have a "next" link regardless of Mojolicious::Plugin::OpenAPI version.
540
    $builder->build_object(
541
        {
542
            class => 'Koha::Cities',
543
            value => {
544
                city_name => 'city1'
545
            }
546
        }
547
    );
548
    $builder->build_object(
549
        {
550
            class => 'Koha::Cities',
551
            value => {
552
                city_name => 'city2'
553
            }
554
        }
555
    );
556
    $builder->build_object(
557
        {
558
            class => 'Koha::Cities',
559
            value => {
560
                city_name => 'city3'
561
            }
562
        }
563
    );
564
565
    my $t = Test::Mojo->new;
566
    $t->get_ok('/cities/rs')->status_is(200)->json_is( '/count' => 3 );
567
568
    $schema->storage->txn_rollback;
569
};
570
511
subtest 'objects.find helper' => sub {
571
subtest 'objects.find helper' => sub {
512
572
513
    plan tests => 9;
573
    plan tests => 9;
Lines 850-852 subtest 'objects.search helper with expanded authorised values' => sub { Link Here
850
910
851
    $schema->storage->txn_rollback;
911
    $schema->storage->txn_rollback;
852
};
912
};
853
- 
913
914
subtest 'objects.find_rs helper' => sub {
915
    plan tests => 9;
916
917
    $schema->storage->txn_begin;
918
919
    # Remove existing cities to have more control on the search results
920
    Koha::Cities->delete;
921
922
 # Create three sample cities that match the query. This makes sure we
923
 # always have a "next" link regardless of Mojolicious::Plugin::OpenAPI version.
924
    my $city1 = $builder->build_object(
925
        {
926
            class => 'Koha::Cities',
927
            value => {
928
                city_name => 'city1'
929
            }
930
        }
931
    );
932
    my $city2 = $builder->build_object(
933
        {
934
            class => 'Koha::Cities',
935
            value => {
936
                city_name => 'city2'
937
            }
938
        }
939
    );
940
    my $city3 = $builder->build_object(
941
        {
942
            class => 'Koha::Cities',
943
            value => {
944
                city_name => 'city3'
945
            }
946
        }
947
    );
948
949
    my $t = Test::Mojo->new;
950
951
    $t->get_ok( '/cities/' . $city1->id . '/rs' )->status_is(200)
952
      ->json_is( '/name' => 'city1' );
953
954
    $t->get_ok( '/cities/' . $city2->id . '/rs' )->status_is(200)
955
      ->json_is( '/name' => 'city2' );
956
957
    $t->get_ok( '/cities/' . $city3->id . '/rs' )->status_is(200)
958
      ->json_is( '/name' => 'city3' );
959
960
    $schema->storage->txn_rollback;
961
};

Return to bug 33080