# 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 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.
+# 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, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# 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 List::MoreUtils qw(any);
use Scalar::Util qw(reftype);
use Koha::Exceptions;
my $reserved_params;
my $filtered_params;
+ my $path_params;
my $reserved_words = _reserved_words();
+ my @query_param_names = keys %{$c->req->params->to_hash};
foreach my $param ( keys %{$params} ) {
if ( grep { $param eq $_ } @{$reserved_words} ) {
$reserved_params->{$param} = $params->{$param};
}
- else {
+ elsif ( grep { $param eq $_ } @query_param_names ) {
$filtered_params->{$param} = $params->{$param};
}
+ else {
+ $path_params->{$param} = $params->{$param};
+ }
}
- return ( $filtered_params, $reserved_params );
+ return ( $filtered_params, $reserved_params, $path_params );
}
);
}
);
+=head3 dbic_merge_prefetch
+
+ $attributes = $c->dbic_merge_prefetch({ attributes => $attributes, result_set => $result_set });
+
+Generates the DBIC prefetch attribute based on embedded relations, and merges into I<$attributes>.
+
+=cut
+
+ $app->helper(
+ 'dbic_merge_prefetch' => sub {
+ my ( $c, $args ) = @_;
+ my $attributes = $args->{attributes};
+ my $result_set = $args->{result_set};
+ my $embed = $c->stash('koha.embed');
+
+ return unless defined $embed;
+
+ my @prefetches;
+ foreach my $key (keys %{$embed}) {
+ my $parsed = _parse_prefetch($key, $embed, $result_set);
+ push @prefetches, $parsed if defined $parsed;
+ }
+
+ if(scalar(@prefetches)) {
+ $attributes->{prefetch} = \@prefetches;
+ }
+ }
+ );
+
=head3 _build_query_params_from_api
my $params = _build_query_params_from_api( $filtered_params, $reserved_params );
return $params;
}
);
+
+=head3 stash_embed
+
+ $c->stash_embed( $c->match->endpoint->pattern->defaults->{'openapi.op_spec'} );
+
+=cut
+
+ $app->helper(
+ 'stash_embed' => sub {
+
+ my ( $c, $args ) = @_;
+
+ my $spec = $args->{spec} // {};
+
+ my $embed_spec = $spec->{'x-koha-embed'};
+ my $embed_header = $c->req->headers->header('x-koha-embed');
+
+ Koha::Exceptions::BadParameter->throw("Embedding objects is not allowed on this endpoint.")
+ if $embed_header and !defined $embed_spec;
+
+ if ( $embed_header ) {
+ my $THE_embed = {};
+ foreach my $embed_req ( split /\s*,\s*/, $embed_header ) {
+ my $matches = grep {lc $_ eq lc $embed_req} @{ $embed_spec };
+
+ Koha::Exceptions::BadParameter->throw(
+ error => 'Embeding '.$embed_req. ' is not authorised. Check your x-koha-embed headers or remove it.'
+ ) unless $matches;
+
+ _merge_embed( _parse_embed($embed_req), $THE_embed);
+ }
+
+ $c->stash( 'koha.embed' => $THE_embed )
+ if $THE_embed;
+ }
+
+ return $c;
+ }
+ );
}
=head2 Internal methods
my $param = $string;
$param =~ s/^(\+|\-|\s)//;
if ( $result_set ) {
- $param = (keys %{$result_set->attributes_from_api({ $param => 1 })})[0];
+ my $model_param = $result_set->from_api_mapping->{$param};
+ $param = $model_param if defined $model_param;
}
if ( $string =~ m/^\+/ or
}
}
+=head3 _parse_embed
+
+ my $embed = _parse_embed( $string );
+
+Parses I<$string> and outputs data valid for passing to the Kohaa::Object(s)->to_api
+method.
+
+=cut
+
+sub _parse_embed {
+ my $string = shift;
+
+ my $result;
+ my ( $curr, $next ) = split /\s*\.\s*/, $string, 2;
+
+ if ( $next ) {
+ $result->{$curr} = { children => _parse_embed( $next ) };
+ }
+ else {
+ if ( $curr =~ m/^(?<relation>.*)\+count/ ) {
+ my $key = $+{relation} . "_count";
+ $result->{$key} = { is_count => 1 };
+ }
+ else {
+ $result->{$curr} = {};
+ }
+ }
+
+ return $result;
+}
+
+=head3 _merge_embed
+
+ _merge_embed( $parsed_embed, $global_embed );
+
+Merges the hash referenced by I<$parsed_embed> into I<$global_embed>.
+
+=cut
+
+sub _merge_embed {
+ my ( $structure, $embed ) = @_;
+
+ my ($root) = keys %{ $structure };
+
+ if ( any { $root eq $_ } keys %{ $embed } ) {
+ # Recurse
+ _merge_embed( $structure->{$root}, $embed->{$root} );
+ }
+ else {
+ # Embed
+ $embed->{$root} = $structure->{$root};
+ }
+}
+
+sub _parse_prefetch {
+ my ( $key, $embed, $result_set) = @_;
+
+ return unless exists $result_set->prefetch_whitelist->{$key};
+
+ my $ko_class = $result_set->prefetch_whitelist->{$key};
+ return $key unless defined $embed->{$key}->{children} && defined $ko_class;
+
+ my $prefetch = {};
+ foreach my $child (keys %{$embed->{$key}->{children}}) {
+ my $parsed = _parse_prefetch($child, $embed->{$key}->{children}, $ko_class->new);
+ $prefetch->{$key} = $parsed if defined $parsed;
+ }
+
+ return unless scalar(keys %{$prefetch});
+
+ return $prefetch;
+}
+
1;