GetModels Filtered: gelaunderten Filter nicht mehr in Controller schreiben
[kivitendo-erp.git] / SL / Controller / Helper / GetModels / Filtered.pm
1 package SL::Controller::Helper::GetModels::Filtered;
2
3 use strict;
4 use parent 'SL::Controller::Helper::GetModels::Base';
5
6 use Exporter qw(import);
7 use SL::Controller::Helper::ParseFilter ();
8 use List::MoreUtils qw(uniq);
9
10 use Rose::Object::MakeMethods::Generic (
11   scalar => [ qw(filter_args filter_params orig_filter filter no_launder) ],
12   'scalar --get_set_init' => [ qw(form_params laundered) ],
13 );
14
15 sub init {
16   my ($self, %specs)             = @_;
17
18   $self->set_get_models(delete $specs{get_models});
19   $self->SUPER::init(%specs);
20
21   $self->get_models->register_handlers(
22     callback   => sub { shift; $self->_callback_handler_for_filtered(@_) },
23   );
24
25   # $::lxdebug->dump(0, "CONSPEC", \%specs);
26 }
27
28 sub read_params {
29   my ($self, %params)   = @_;
30
31   return %{ $self->filter_params } if $self->filter_params;
32   my $source = $self->get_models->source;
33
34   my $filter            = $self->filter // $source->{ $self->form_params } // {};
35   $self->orig_filter($filter);
36
37   my %filter_args       = $self->_get_filter_args;
38   my %parse_filter_args = (
39     class        => $self->get_models->manager,
40     with_objects => $params{with_objects},
41   );
42
43   # Store laundered result in $self->laundered.
44
45   if (!$self->no_launder) {
46     $self->laundered({});
47     $parse_filter_args{launder_to} = $self->laundered;
48   } else {
49     $self->laundered(undef);
50     $parse_filter_args{no_launder} = 1;
51   }
52
53   my %calculated_params = SL::Controller::Helper::ParseFilter::parse_filter($filter, %parse_filter_args);
54   %calculated_params = $self->merge_args(\%calculated_params, \%filter_args, \%params);
55
56   # $::lxdebug->dump(0, "get_current_filter_params: ", \%calculated_params);
57
58   $self->filter_params(\%calculated_params);
59
60   return %calculated_params;
61 }
62
63 sub finalize {
64   my ($self, %params) = @_;
65
66   my %filter_params;
67   %filter_params = $self->read_params(%params)  if $self->is_enabled;
68
69   # $::lxdebug->dump(0, "GM handler for filtered; params nach modif (is_enabled? " . $self->is_enabled . ")", \%params);
70
71   return $self->merge_args(\%params, \%filter_params);
72 }
73
74 #
75 # private functions
76 #
77
78 sub _get_filter_args {
79   my ($self, $spec) = @_;
80
81   my %filter_args   = ref($self->filter_args) eq 'CODE' ? %{ $self->filter_args->($self) }
82                     :     $self->filter_args            ? do { my $sub = $self->filter_args; %{ $self->get_models->controller->$sub() } }
83                     :                                       ();
84 }
85
86 sub _callback_handler_for_filtered {
87   my ($self, %params) = @_;
88
89   if ($self->is_enabled) {
90     my ($flattened) = SL::Controller::Helper::ParseFilter::flatten($self->orig_filter, $self->form_params);
91     %params         = (%params, @{ $flattened || [] });
92   }
93
94   # $::lxdebug->dump(0, "CB handler for filtered; params after flatten:", \%params);
95
96   return %params;
97 }
98
99 sub init_form_params {
100   'filter'
101 }
102
103 sub init_laundered {
104   my ($self) = @_;
105
106   $self->get_models->finalize;
107   return $self->{laundered};
108 }
109
110 1;
111
112 __END__
113
114 =pod
115
116 =encoding utf8
117
118 =head1 NAME
119
120 SL::Controller::Helper::GetModels::Filtered - Filter handling plugin for GetModels
121
122 =head1 SYNOPSIS
123
124 In a controller:
125
126   SL::Controller::Helper::GetModels->new(
127     ...
128     filtered => {
129       filter      => HASHREF,
130       no_launder  => 0 | 1,
131     }
132
133     OR
134
135     filtered => 0,
136   );
137
138 =head1 OVERVIEW
139
140 This C<GetModels> plugin enables use of the
141 L<SL::Controller::Helper::ParseFilter> methods. Additional filters can be
142 defined in the database models and filtering can be reduced to a minimum of
143 work.
144
145 The underlying functionality that enables the use of more than just
146 the paginate helper is provided by the controller helper
147 C<GetModels>. See the documentation for L<SL::Controller::Helper::GetModels> for
148 more information on it.
149
150 =head1 OPTIONS
151
152 =over 4
153
154 =item * C<filter>
155
156 Optional. Indicates a key in C<source> to be used as filter.
157
158 Defaults to the value C<filter> if missing.
159
160 =item * C<no_launder>
161
162 Optional. If given and trueish then laundering is disabled.
163
164 =back
165
166 =head1 FILTER FORMAT
167
168 See L<SL::Controller::Helper::ParseFilter> for a description of the filter format.
169
170 =head1 CUSTOM FILTERS
171
172 C<Filtered> will honor custom filters defined in RDBO managers. See
173 L<SL::DB::Helper::Filtered> for an explanation fo those.
174
175 =head1 FUNCTIONS
176
177 =over 4
178
179 =item C<laundered>
180
181 Finalizes the object (which causes laundering of the filter structure)
182 and returns a hashref of the laundered filter. If the plugin is
183 configured not to launder then C<undef> will be returned.
184
185 =back
186
187 =head1 BUGS
188
189 =over 4
190
191 =item * There is currently no easy way to filter for CVars.
192
193 =back
194
195 =head1 AUTHOR
196
197 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
198
199 =cut