Bug 37902: Make sure we loop over if a structure is passed

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Katrin Fischer <katrin.fischer@bsz-bw.de>
This commit is contained in:
Jonathan Druart 2024-09-12 11:19:36 +02:00 committed by Katrin Fischer
parent e36db00fa1
commit 101fd97cb7
No known key found for this signature in database
GPG Key ID: 0EF6E2C03357A834
3 changed files with 74 additions and 36 deletions

View File

@ -832,6 +832,44 @@ Returns the passed params, converted from API naming into the model.
=cut
sub _recursive_fixup {
my ( $self, $key, $value, $column_info ) = @_;
if ( ref($value) && ref($value) eq 'HASH' ) {
my $hash;
for my $k ( keys %$value ) {
$hash->{$k} = $self->_recursive_fixup( $key, $value->{$k}, $column_info );
}
return $hash;
} elsif ( ref($value) && ref($value) eq 'ARRAY' ) {
return [ map { $self->_recursive_fixup( $key, $_, $column_info ) } @$value ];
} else {
if ( $column_info->{is_boolean} ) {
# TODO: Remove when D8 is formally deprecated
# Handle booleans gracefully
$value = ($value) ? 1 : 0;
} elsif ( _date_or_datetime_column_type( $column_info->{data_type} ) ) {
if ( defined $value ) {
try {
my $dtf = $self->_result->result_source->storage->datetime_parser;
if ( $column_info->{data_type} eq 'date' ) {
my $dt = DateTime::Format::MySQL->parse_date($value);
$value = $dtf->format_date($dt);
} else {
my $dt = Koha::DateTime::Format::RFC3339->parse_datetime($value);
$value = $dtf->format_datetime($dt);
}
} catch {
Koha::Exceptions::BadParameter->throw( parameter => $key );
};
}
}
return $value;
}
}
sub attributes_from_api {
my ( $self, $from_api_params ) = @_;
@ -839,38 +877,14 @@ sub attributes_from_api {
my $params;
my $columns_info = $self->_result->result_source->columns_info;
my $dtf = $self->_result->result_source->storage->datetime_parser;
while (my ($key, $value) = each %{ $from_api_params } ) {
while ( my ( $key, $value ) = each %{$from_api_params} ) {
my $koha_field_name =
exists $from_api_mapping->{$key}
? $from_api_mapping->{$key}
: $key;
exists $from_api_mapping->{$key}
? $from_api_mapping->{$key}
: $key;
if ( $columns_info->{$koha_field_name}->{is_boolean} ) {
# TODO: Remove when D8 is formally deprecated
# Handle booleans gracefully
$value = ( $value ) ? 1 : 0;
}
elsif ( _date_or_datetime_column_type( $columns_info->{$koha_field_name}->{data_type} ) ) {
if (defined $value) {
try {
if ( $columns_info->{$koha_field_name}->{data_type} eq 'date' ) {
my $dt = DateTime::Format::MySQL->parse_date($value);
$value = $dtf->format_date($dt);
}
else {
my $dt = Koha::DateTime::Format::RFC3339->parse_datetime($value);
$value = $dtf->format_datetime($dt);
}
}
catch {
Koha::Exceptions::BadParameter->throw( parameter => $key );
};
}
}
$params->{$koha_field_name} = $value;
$params->{$koha_field_name} = $self->_recursive_fixup( $key, $value, $columns_info->{$koha_field_name} );
}
return $params;

View File

@ -274,13 +274,15 @@ controller, and thus shouldn't be called twice in it.
# Apply the mapping function to the passed params
if ( defined $filtered_params ) {
$filtered_params =
$c->build_query_params( $filtered_params, $reserved_params );
}
$filtered_params = $c->build_query_params( $filtered_params, $reserved_params );
}
$filtered_params =
$c->merge_q_params( $filtered_params, $query_params,
$result_set );
if ($query_params) {
$filtered_params = $c->merge_q_params(
$filtered_params, $query_params,
$result_set
);
}
$filtered_params =
$result_set->attributes_from_api($filtered_params);

View File

@ -763,7 +763,7 @@ subtest 'attributes_from_api() tests' => sub {
subtest 'date and date-time handling tests' => sub {
plan tests => 12;
plan tests => 13;
my $patron = Koha::Patron->new();
@ -803,6 +803,28 @@ subtest 'attributes_from_api() tests' => sub {
'Given an rfc3339 formatted date string, a date field is converted into an SQL formatted date string'
);
$attrs = $patron->attributes_from_api(
{
updated_on => { '>' => '2019-12-27T14:53:00Z' },
last_seen => [ { '>' => '2019-12-27T14:53:00Z' }, { '=' => '2019-12-31T23:59:00Z' } ],
date_of_birth => [ { '>' => '2019-12-27' }, { '=' => '2019-12-31' } ],
}
);
is_deeply(
$attrs,
{
lastseen => [
{
'>' => '2019-12-27 14:53:00',
},
{ '=' => '2019-12-31 23:59:00' }
],
updated_on => { '>' => '2019-12-27 14:53:00' },
dateofbirth => [ { '>', '2019-12-27'}, { '=' => '2019-12-31' } ]
}
);
$attrs = $patron->attributes_from_api(
{
last_seen => undef,