Koha-clms/Koha/REST/Plugin/Objects.pm

300 lines
9.1 KiB
Perl

package Koha::REST::Plugin::Objects;
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use Mojo::Base 'Mojolicious::Plugin';
use JSON;
=head1 NAME
Koha::REST::Plugin::Objects
=head1 API
=head2 Helper methods
=cut
sub register {
my ( $self, $app ) = @_;
=head3 objects.find
my $patrons_rs = Koha::Patrons->new;
my $patrons = $c->objects->find( $patrons_rs, $id );
. . .
return $c->render({ status => 200, openapi => $patron });
Performs a database search using given Koha::Objects object and the $id.
Returns I<undef> if no object is found or the I<API representation> of
the requested object including any embeds specified in the request.
=cut
$app->helper(
'objects.find' => sub {
my ( $c, $result_set, $id ) = @_;
my $object = $c->objects->find_rs( $result_set, $id );
return unless $object;
return $c->objects->to_api($object);
}
);
=head3 objects.find_rs
my $patrons_rs = Koha::Patrons->new;
my $patron_rs = $c->objects->find_rs( $patrons_rs, $id );
. . .
return $c->render({ status => 200, openapi => $patron_rs->to_api });
Returns the passed Koha::Object result filtered to the passed $id and
with any embeds requested by the api applied.
The result object can then be used for further processing.
=cut
$app->helper(
'objects.find_rs' => sub {
my ( $c, $result_set, $id ) = @_;
my $attributes = {};
# Generate prefetches for embedded stuff
$c->dbic_merge_prefetch(
{
attributes => $attributes,
result_set => $result_set
}
);
my $object = $result_set->find( $id, $attributes );
return $object;
}
);
=head3 objects.search
my $patrons_rs = Koha::Patrons->new;
my $patrons = $c->objects->search( $patrons_rs );
. . .
return $c->render({ status => 200, openapi => $patrons });
Performs a database search using given Koha::Objects object with any api
query parameters applied.
Returns an arrayref of I<API representations> of the requested objects
including any embeds specified in the request.
Warning: this helper adds pagination headers to the calling controller, and thus
shouldn't be called twice in it.
=cut
$app->helper(
'objects.search' => sub {
my ( $c, $result_set ) = @_;
# Generate the resultset using the HTTP request information
my $objects_rs = $c->objects->search_rs($result_set);
# Add pagination headers
$c->add_pagination_headers();
return $c->objects->to_api($objects_rs);
}
);
=head3 objects.search_rs
my $patrons_object = Koha::Patrons->new;
my $patrons_rs = $c->objects->search_rs( $patrons_object );
. . .
return $c->render({ status => 200, openapi => $patrons_rs->to_api });
Returns the passed Koha::Objects resultset filtered as requested by the api query
parameters and with requested embeds applied.
Warning: this helper stashes base values for the pagination headers to the calling
controller, and thus shouldn't be called twice in it.
=cut
$app->helper(
'objects.search_rs' => sub {
my ( $c, $result_set ) = @_;
my $args = $c->validation->output;
my $attributes = {};
# Extract reserved params
my ( $filtered_params, $reserved_params, $path_params ) =
$c->extract_reserved_params($args);
# Merge sorting into query attributes
$c->dbic_merge_sorting(
{
attributes => $attributes,
params => $reserved_params,
result_set => $result_set
}
);
# If no pagination parameters are passed, default
$reserved_params->{_per_page} //=
C4::Context->preference('RESTdefaultPageSize') // 20;
$reserved_params->{_page} //= 1;
$c->stash('koha.pagination.page' => $reserved_params->{_page});
$c->stash('koha.pagination.per_page' => $reserved_params->{_per_page});
unless ( $reserved_params->{_per_page} == -1 ) {
# Merge pagination into query attributes
$c->dbic_merge_pagination(
{
filter => $attributes,
params => $reserved_params
}
);
}
# Generate prefetches for embedded stuff
$c->dbic_merge_prefetch(
{
attributes => $attributes,
result_set => $result_set
}
);
# Call the to_model function by reference, if defined
if ( defined $filtered_params ) {
# Apply the mapping function to the passed params
$filtered_params =
$result_set->attributes_from_api($filtered_params);
$filtered_params =
$c->build_query_params( $filtered_params, $reserved_params );
}
if ( defined $reserved_params->{q}
|| defined $reserved_params->{query}
|| defined $reserved_params->{'x-koha-query'} )
{
$filtered_params //= {};
my @query_params_array;
# query in request body, JSON::Validator already decoded it
push @query_params_array, $reserved_params->{query}
if defined $reserved_params->{query};
my $json = JSON->new;
if ( ref( $reserved_params->{q} ) eq 'ARRAY' ) {
# q is defined as multi => JSON::Validator generates an array
foreach my $q ( @{ $reserved_params->{q} } ) {
push @query_params_array, $json->decode($q)
if $q; # skip if exists but is empty
}
}
else {
# objects.search called outside OpenAPI context
# might be a hashref
push @query_params_array,
$json->decode( $reserved_params->{q} )
if $reserved_params->{q};
}
push @query_params_array,
$json->decode( $reserved_params->{'x-koha-query'} )
if defined $reserved_params->{'x-koha-query'};
my $query_params;
if ( scalar(@query_params_array) > 1 ) {
$query_params = { '-and' => \@query_params_array };
}
else {
$query_params = $query_params_array[0];
}
$filtered_params =
$c->merge_q_params( $filtered_params, $query_params,
$result_set );
}
# request sequence id (i.e. 'draw' Datatables parameter)
$c->res->headers->add(
'x-koha-request-id' => $reserved_params->{'x-koha-request-id'} )
if $reserved_params->{'x-koha-request-id'};
# If search_limited exists, use it
$result_set = $result_set->search_limited,
if $result_set->can('search_limited');
$c->stash('koha.pagination.base_total' => $result_set->count);
$c->stash('koha.pagination.query_params' => $args);
# Generate the resultset
my $objects_rs = $result_set->search( $filtered_params, $attributes );
# Stash the page total if requires, total otherwise
$c->stash('koha.pagination.total' => $objects_rs->is_paged ? $objects_rs->pager->total_entries : $objects_rs->count);
return $objects_rs;
}
);
=head3 objects.to_api
my $patrons_rs = Koha::Patrons->new;
my $api_representation = $c->objects->to_api( $patrons_rs );
Returns the API representation of the passed resultset.
=cut
$app->helper(
'objects.to_api' => sub {
my ( $c, $object ) = @_;
# Privileged request?
my $public = $c->stash('is_public');
# Look for embeds
my $embed = $c->stash('koha.embed');
my $strings = $c->stash('koha.strings');
return $object->to_api(
{
embed => $embed,
public => $public,
strings => $strings
}
);
}
);
}
1;