Bug 24228: Add parameters to Koha::Object(s)->to_api to automatically embed objects
This patch makes Koha::Object(s)->to_api have an 'embeds' parameter that using dot notation (e.g. resource.related_resource.another_one) allows embedding objects recursively. To test: 1. Apply this patch 2. prove t/db_dependent/Koha/Object.t Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io> Signed-off-by: Agustin Moyano <agustinmoyano@theke.io> Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com> Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
This commit is contained in:
parent
9bcf22b0d5
commit
f87ebb9ab1
|
|
@ -381,25 +381,57 @@ Returns a representation of the object, suitable for API output.
|
|||
=cut
|
||||
|
||||
sub to_api {
|
||||
my ( $self ) = @_;
|
||||
my ( $self, $embeds ) = @_;
|
||||
my $json_object = $self->TO_JSON;
|
||||
|
||||
my $to_api_mapping = $self->to_api_mapping;
|
||||
|
||||
# Rename attributes if there's a mapping
|
||||
foreach my $column ( keys %{$to_api_mapping} ) {
|
||||
my $mapped_column = $to_api_mapping->{$column};
|
||||
if ( exists $json_object->{$column}
|
||||
&& defined $mapped_column )
|
||||
{
|
||||
# key != undef
|
||||
$json_object->{$mapped_column} = delete $json_object->{$column};
|
||||
if ( $self->can('to_api_mapping') ) {
|
||||
foreach my $column ( keys %{ $self->to_api_mapping } ) {
|
||||
my $mapped_column = $self->to_api_mapping->{$column};
|
||||
if ( exists $json_object->{$column}
|
||||
&& defined $mapped_column )
|
||||
{
|
||||
# key != undef
|
||||
$json_object->{$mapped_column} = delete $json_object->{$column};
|
||||
}
|
||||
elsif ( exists $json_object->{$column}
|
||||
&& !defined $mapped_column )
|
||||
{
|
||||
# key == undef
|
||||
delete $json_object->{$column};
|
||||
}
|
||||
}
|
||||
elsif ( exists $json_object->{$column}
|
||||
&& !defined $mapped_column )
|
||||
{
|
||||
# key == undef
|
||||
delete $json_object->{$column};
|
||||
}
|
||||
|
||||
if ($embeds) {
|
||||
foreach my $embed (@$embeds) {
|
||||
my ( $curr, $next ) = split /\s*\.\s*/, $embed, 2;
|
||||
my @nxembeds;
|
||||
|
||||
@nxembeds = ($next) if $next;
|
||||
|
||||
my $children = $self->$curr;
|
||||
if ( ref $children eq 'ARRAY' ) {
|
||||
my @list;
|
||||
my $pos = 0;
|
||||
foreach my $child (@$children) {
|
||||
my $res = $child->to_api( \@nxembeds );
|
||||
$res = { $json_object->{$curr}->[$pos], $res }
|
||||
if defined $json_object->{$curr}
|
||||
&& defined $json_object->{$curr}->[$pos];
|
||||
push @list, $res;
|
||||
$pos++;
|
||||
}
|
||||
$json_object->{$curr} = \@list;
|
||||
}
|
||||
else {
|
||||
my $res = $children->to_api( \@nxembeds );
|
||||
$res = { $json_object->{$curr}, $res }
|
||||
if defined $json_object->{$curr};
|
||||
$json_object->{$curr} = $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -315,9 +315,9 @@ Returns a representation of the objects, suitable for API output .
|
|||
=cut
|
||||
|
||||
sub to_api {
|
||||
my ($self) = @_;
|
||||
my ($self, $embeds) = @_;
|
||||
|
||||
return [ map { $_->to_api } $self->as_list ];
|
||||
return [ map { $_->to_api($embeds) } $self->as_list ];
|
||||
}
|
||||
|
||||
=head3 attributes_from_api
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ subtest 'TO_JSON tests' => sub {
|
|||
|
||||
subtest "to_api() tests" => sub {
|
||||
|
||||
plan tests => 11;
|
||||
plan tests => 18;
|
||||
|
||||
$schema->storage->txn_begin;
|
||||
|
||||
|
|
@ -262,6 +262,44 @@ subtest "to_api() tests" => sub {
|
|||
my $illrequest = $builder->build_object({ class => 'Koha::Illrequests' });
|
||||
is_deeply( $illrequest->to_api, $illrequest->TO_JSON, 'If no overloaded to_api_mapping method, return TO_JSON' );
|
||||
|
||||
my $item_class = Test::MockModule->new('Koha::Item');
|
||||
$item_class->mock( 'to_api_mapping',
|
||||
sub {
|
||||
return {
|
||||
itemnumber => 'item_id'
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
my $hold_class = Test::MockModule->new('Koha::Hold');
|
||||
$hold_class->mock( 'to_api_mapping',
|
||||
sub {
|
||||
return {
|
||||
reserve_id => 'hold_id'
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
my $biblio = $builder->build_sample_biblio();
|
||||
my $item = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
|
||||
my $hold = $builder->build_object({ class => 'Koha::Holds', value => { itemnumber => $item->itemnumber } });
|
||||
|
||||
my @embeds = ('items');
|
||||
|
||||
my $biblio_api = $biblio->to_api(\@embeds);
|
||||
|
||||
ok(exists $biblio_api->{items}, 'Items where embedded in biblio results');
|
||||
is($biblio_api->{items}->[0]->{item_id}, $item->itemnumber, 'Item matches');
|
||||
ok(!exists $biblio_api->{items}->[0]->{holds}, 'No holds info should be embedded yet');
|
||||
|
||||
@embeds = ('items.holds');
|
||||
$biblio_api = $biblio->to_api(\@embeds);
|
||||
|
||||
ok(exists $biblio_api->{items}, 'Items where embedded in biblio results');
|
||||
is($biblio_api->{items}->[0]->{item_id}, $item->itemnumber, 'Item still matches');
|
||||
ok(exists $biblio_api->{items}->[0]->{holds}, 'Holds info should be embedded');
|
||||
is($biblio_api->{items}->[0]->{holds}->[0]->{hold_id}, $hold->reserve_id, 'Hold matches');
|
||||
|
||||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue