From a62f745be4cb1717acff532ec27f3e22a0095f08 Mon Sep 17 00:00:00 2001 From: Marcel de Rooy Date: Mon, 13 Sep 2021 08:05:11 +0000 Subject: [PATCH] Bug 29029: Introduce Koha::Object::ColumnSet Content-Type: text/plain; charset=utf-8 --- Koha/Object.pm | 26 +++++++++ Koha/Object/ColumnSet.pm | 110 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 Koha/Object/ColumnSet.pm diff --git a/Koha/Object.pm b/Koha/Object.pm index 6f55c3b486..20f9530a26 100644 --- a/Koha/Object.pm +++ b/Koha/Object.pm @@ -29,6 +29,7 @@ use Koha::Database; use Koha::Exceptions::Object; use Koha::DateUtils qw( dt_from_string output_pref ); use Koha::Object::Message; +use Koha::Object::ColumnSet; =head1 NAME @@ -784,6 +785,31 @@ sub _columns { return $self->{_columns}; } +=head3 filter + + my $some_columns = $self->filter({ column_set => $column_set_name }); + + Filters the object data through the specified column set (defined in + schema file). + Allows filtering other input (hashref) by including input => $input. + When you pass deny_mode => 1, the column set is used as a deny list. + Normally, it is considered as an allow list. + Diagnostics via dump => $dump, logging via log_level => $log_level. + Note: $dump contains the blocked/discarded entries. + Log level is debug, warn, etc. + +=cut + +sub filter { + my ( $self, $params ) = @_; + my $set = Koha::Object::ColumnSet->new({ rs => $self->_result, name => $params->{column_set} }); + return $set->apply_filter({ input => $params->{input}, deny_mode => $params->{deny_mode}, log_level => $params->{log_level}, dump => $params->{dump} }); +} + +=head3 _get_object_class + +=cut + sub _get_object_class { my ( $type ) = @_; return unless $type; diff --git a/Koha/Object/ColumnSet.pm b/Koha/Object/ColumnSet.pm new file mode 100644 index 0000000000..311c6a18f8 --- /dev/null +++ b/Koha/Object/ColumnSet.pm @@ -0,0 +1,110 @@ +package Koha::Object::ColumnSet; + +# 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 . + +use Modern::Perl; +use Carp (); +use Data::Dumper (); + +use Koha::Logger (); + +=head1 NAME + +Koha::Object::ColumnSet + +=head1 API + +=head2 Class Methods + +=head3 new + + Constructor. + +=cut + +sub new { + my ( $class, $params ) = @_; # parameter hash keys: rs, name + my $self = bless( $params, $class ); + $self->_get_column_set; + return $self; +} + +sub _get_column_set { + my ( $self ) = @_; + my $rs = $self->{rs} or return; + my $name = $self->{name} or return; + + # If the schema does not contain this sub, _list will not be set. + # If the sub exists but the name of the set is not found, _list will be undef. + # See further apply_filter. + if( $rs->can('get_column_set') ) { + $self->{_list} = $rs->get_column_set($name); + } +} + +=head3 apply_filter + + $set->apply_filter({ input => $input, deny_mode => $deny_mode, log_level => $log_level, dump => $dump }); + + Apply column set filter to $input or the passed resultset (see new). + $deny_mode turns the column set into a deny list. + Diagnostics and logging via $dump and $log_level. + + NOTE: Returns all data if schema does not support get_column_set yet. Returns undef if set not found. + +=cut + +sub apply_filter { + my ( $self, $params ) = @_; + my $data = $params->{input} // { $self->{rs}->get_columns }; + my $log_level = $params->{log_level}; + return $data if !exists( $self->{_list} ); # no get_column_set in schema, just return all data + return unless $self->{_list}; # no results if the specific column set is not found + + my ( $result, $blocked ); + unless( $params->{deny_mode} ) { # as allow list + $result = { map { exists $data->{$_} ? ($_, $data->{$_}) : () } @{$self->{_list}} }; + } else { # as deny list + $result = { %$data }; + map { delete $result->{$_} } @{$self->{_list}}; + } + + # Handle optional diagnostics, logging + if( $params->{dump} || $log_level ) { + $blocked = { map { !exists $result->{$_} ? ($_, $data->{$_}) : () } keys %$data }; + map { $params->{dump}->{$_} = $blocked->{$_} } keys %$blocked if $params->{dump}; + if( $log_level && keys %$blocked ) { + my $stack = Carp::longmess; $stack =~ s/\n/, /g; + my $diag = Data::Dumper->new([ $stack, $blocked ])->Indent(0)->Dump; + Koha::Logger->get->$log_level( $diag ); + } + } + + return $result; +} + +=head3 list_columns + + $set->list_columns + +=cut + +sub list_columns { + my ( $self ) = @_; + return [ sort @{$self->{_list}} ] if $self->{_list}; +} + +1; -- 2.20.1