235 lines
6.9 KiB
Perl
235 lines
6.9 KiB
Perl
package Koha::Objects::Mixin::ExtendedAttributes;
|
|
|
|
# Copyright 2024 PTFS Europe Ltd
|
|
#
|
|
# 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 Scalar::Util qw( reftype );
|
|
|
|
=head1 NAME
|
|
|
|
Koha::Objects::Mixin::ExtendedAttributes
|
|
|
|
=head2 Class methods
|
|
|
|
|
|
=head3 search
|
|
|
|
Overwrites the search method to include extended attributes rewrite and dynamic relation accessors
|
|
|
|
=cut
|
|
|
|
sub search {
|
|
my ( $self, $params, $attributes ) = @_;
|
|
|
|
my $class = ref($self) ? ref($self) : $self;
|
|
|
|
$self->handle_query_extended_attributes(
|
|
{
|
|
attributes => $attributes,
|
|
filtered_params => $params,
|
|
}
|
|
);
|
|
|
|
my $rs = $self->_resultset()->search( $params, $attributes );
|
|
return $class->_new_from_dbic($rs);
|
|
}
|
|
|
|
=head3 handle_query_extended_attributes
|
|
|
|
Checks for the presence of extended_attributes in a query
|
|
If present, it builds the dynamic extended attributes relations and rewrites the query to include the extended_attributes relation
|
|
|
|
=cut
|
|
|
|
sub handle_query_extended_attributes {
|
|
my ( $self, $args ) = @_;
|
|
|
|
my $attributes = $args->{attributes};
|
|
my $filtered_params = $args->{filtered_params};
|
|
|
|
if ( reftype( $attributes->{prefetch} )
|
|
&& reftype( $attributes->{prefetch} ) eq 'ARRAY'
|
|
&& grep ( /extended_attributes/, @{ $attributes->{prefetch} } ) )
|
|
{
|
|
|
|
my @array = $self->_get_extended_attributes_entries($filtered_params);
|
|
|
|
# Calling our private method to build the extended attributes relations
|
|
my @joins = $self->_build_extended_attributes_relations( \@array );
|
|
push @{ $attributes->{join} }, @joins;
|
|
|
|
}
|
|
}
|
|
|
|
=head3 _get_extended_attributes_entries
|
|
|
|
$self->_get_extended_attributes_entries( $filtered_params, 0 )
|
|
|
|
Recursive function that returns the rewritten extended_attributes query entries.
|
|
|
|
Given:
|
|
[
|
|
'-and',
|
|
[
|
|
{
|
|
'extended_attributes.code' => 'CODE_1',
|
|
'extended_attributes.attribute' => { 'like' => '%Bar%' }
|
|
},
|
|
{
|
|
'extended_attributes.attribute' => { 'like' => '%Bar%' },
|
|
'extended_attributes.code' => 'CODE_2'
|
|
}
|
|
]
|
|
];
|
|
|
|
Returns :
|
|
|
|
[
|
|
'CODE_1',
|
|
'CODE_2'
|
|
]
|
|
|
|
=cut
|
|
|
|
sub _get_extended_attributes_entries {
|
|
my ( $self, $params, @array ) = @_;
|
|
|
|
if ( reftype($params) && reftype($params) eq 'HASH' ) {
|
|
|
|
# rewrite additional_field_values table query params
|
|
@array = _rewrite_related_metadata_query( $params, 'field_id', 'value', @array )
|
|
if $params->{'extended_attributes.field_id'};
|
|
|
|
# rewrite borrower_attributes table query params
|
|
@array = _rewrite_related_metadata_query( $params, 'code', 'attribute', @array )
|
|
if $params->{'extended_attributes.code'};
|
|
|
|
# rewrite illrequestattributes table query params
|
|
@array = _rewrite_related_metadata_query( $params, 'type', 'value', @array )
|
|
if $params->{'extended_attributes.type'};
|
|
|
|
foreach my $key ( keys %{$params} ) {
|
|
return $self->_get_extended_attributes_entries( $params->{$key}, @array );
|
|
}
|
|
} elsif ( reftype($params) && reftype($params) eq 'ARRAY' ) {
|
|
foreach my $ea_instance (@$params) {
|
|
@array = $self->_get_extended_attributes_entries( $ea_instance, @array );
|
|
}
|
|
return @array;
|
|
} else {
|
|
return @array;
|
|
}
|
|
}
|
|
|
|
=head3 _rewrite_related_metadata_query
|
|
|
|
$extended_attributes_entries =
|
|
_rewrite_related_metadata_query( $params, 'field_id', 'value', @array )
|
|
|
|
Helper function that rewrites all subsequent extended_attributes queries to match the alias generated by the dbic self left join
|
|
Take the below example (patrons):
|
|
[
|
|
{
|
|
"extended_attributes.attribute":{"like":"%123%"},
|
|
"extended_attributes.code":"CODE_1"
|
|
}
|
|
],
|
|
[
|
|
{
|
|
"extended_attributes.attribute":{"like":"%abc%" },
|
|
"extended_attributes.code":"CODE_2"
|
|
}
|
|
]
|
|
|
|
It'll be rewritten as:
|
|
[
|
|
{
|
|
'extended_attributes_CODE_1.attribute' => { 'like' => '%123%' },
|
|
'extended_attributes_CODE_1.code' => 'CODE_1'
|
|
}
|
|
],
|
|
[
|
|
{
|
|
'extended_attributes_CODE_2.attribute' => { 'like' => '%abc%' },
|
|
'extended_attributes_CODE_2.code' => 'CODE_2'
|
|
}
|
|
]
|
|
|
|
=cut
|
|
|
|
sub _rewrite_related_metadata_query {
|
|
my ( $params, $key, $value, @array ) = @_;
|
|
|
|
if ( ref \$params->{ 'extended_attributes.' . $key } eq 'SCALAR' ) {
|
|
my $old_key_value = delete $params->{ 'extended_attributes.' . $key };
|
|
my $new_key_value = "extended_attributes_$old_key_value" . "." . $key;
|
|
$params->{$new_key_value} = $old_key_value;
|
|
|
|
my $old_value_value = delete $params->{ 'extended_attributes.' . $value };
|
|
my $new_value_value = "extended_attributes_$old_key_value" . "." . $value;
|
|
$params->{$new_value_value} = $old_value_value;
|
|
push @array, $old_key_value;
|
|
}
|
|
|
|
return @array;
|
|
}
|
|
|
|
=head3 _build_extended_attributes_relations
|
|
|
|
Method to dynamically add has_many relations for Koha classes that support extended_attributes.
|
|
|
|
Returns a list of relation accessor names.
|
|
|
|
=cut
|
|
|
|
sub _build_extended_attributes_relations {
|
|
my ( $self, $types ) = @_;
|
|
|
|
return if ( !grep ( /extended_attributes/, keys %{ $self->_resultset->result_source->_relationships } ) );
|
|
|
|
my $ea_config = $self->extended_attributes_config;
|
|
|
|
my $result_source = $self->_resultset->result_source;
|
|
for my $type ( @{$types} ) {
|
|
$result_source->add_relationship(
|
|
"extended_attributes_$type",
|
|
"$ea_config->{schema_class}",
|
|
sub {
|
|
my $args = shift;
|
|
|
|
return {
|
|
"$args->{foreign_alias}.$ea_config->{id_field}->{foreign}" =>
|
|
{ -ident => "$args->{self_alias}.$ea_config->{id_field}->{self}" },
|
|
"$args->{foreign_alias}.$ea_config->{key_field}" => { '=', $type },
|
|
};
|
|
},
|
|
{
|
|
accessor => 'multi',
|
|
join_type => 'LEFT',
|
|
cascade_copy => 0,
|
|
cascade_delete => 0,
|
|
is_depends_on => 0
|
|
},
|
|
);
|
|
|
|
}
|
|
return map { 'extended_attributes_' . $_ } @{$types};
|
|
}
|
|
|
|
1;
|