1 package SL::Controller::Helper::GetModels::Filtered;
4 use parent 'SL::Controller::Helper::GetModels::Base';
6 use Exporter qw(import);
7 use SL::Controller::Helper::ParseFilter ();
8 use List::MoreUtils qw(uniq);
10 use Rose::Object::MakeMethods::Generic (
11 scalar => [ qw(filter_args filter_params orig_filter) ],
12 'scalar --get_set_init' => [ qw(form_params launder_to) ],
16 my ($self, %specs) = @_;
18 $self->set_get_models(delete $specs{get_models});
19 $self->SUPER::init(%specs);
21 $self->get_models->register_handlers(
22 callback => sub { shift; $self->_callback_handler_for_filtered(@_) },
23 get_models => sub { shift; $self->_get_models_handler_for_filtered(@_) },
26 # $::lxdebug->dump(0, "CONSPEC", \%specs);
30 my ($self, %params) = @_;
32 return %{ $self->filter_params } if $self->filter_params;
33 my $source = $self->get_models->source;
35 my $filter = $params{filter} // $source->{ $self->form_params } // {};
36 $self->orig_filter($filter);
38 my %filter_args = $self->_get_filter_args;
39 my %parse_filter_args = (
40 class => $self->get_models->manager,
41 with_objects => $params{with_objects},
44 if ($self->launder_to eq '__INPLACE__') {
46 } elsif ($self->launder_to) {
48 $parse_filter_args{launder_to} = $laundered;
50 $parse_filter_args{no_launder} = 1;
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);
57 if ($self->get_models->controller->can($self->launder_to)) {
58 $self->get_models->controller->${\ $self->launder_to }($laundered);
60 $self->get_models->controller->{$self->launder_to} = $laundered;
64 # $::lxdebug->dump(0, "get_current_filter_params: ", \%calculated_params);
66 $self->filter_params(\%calculated_params);
68 return %calculated_params;
72 my ($self, %params) = @_;
80 sub _get_filter_args {
81 my ($self, $spec) = @_;
83 my %filter_args = ref($self->filter_args) eq 'CODE' ? %{ $self->filter_args->($self) }
84 : $self->filter_args ? do { my $sub = $self->filter_args; %{ $self->get_models->controller->$sub() } }
88 sub _callback_handler_for_filtered {
89 my ($self, %params) = @_;
91 if ($self->is_enabled) {
92 my ($flattened) = SL::Controller::Helper::ParseFilter::flatten($self->orig_filter, $self->form_params);
93 %params = (%params, @{ $flattened || [] });
96 # $::lxdebug->dump(0, "CB handler for filtered; params after flatten:", \%params);
101 sub _get_models_handler_for_filtered {
102 my ($self, %params) = @_;
104 # $::lxdebug->dump(0, "params in get_models_for_filtered", \%params);
107 %filter_params = $self->read_params(%params) if $self->is_enabled;
109 # $::lxdebug->dump(0, "GM handler for filtered; params nach modif (is_enabled? " . $self->is_enabled . ")", \%params);
111 return $self->merge_args(\%params, \%filter_params);
114 sub init_form_params {
118 sub init_launder_to {
133 SL::Controller::Helper::Filtered - A helper for semi-automatic handling
134 of filtered lists of database models in a controller
140 use SL::Controller::Helper::GetModels;
141 use SL::Controller::Helper::Filtered;
143 __PACKAGE__->make_filter(
145 ONLY => [ qw(list) ],
146 FORM_PARAMS => [ qw(filter) ],
152 my $filtered_models = $self->get_models(%addition_filters);
153 $self->render('controller/list', ENTRIES => $filtered_models);
159 This helper module enables use of the L<SL::Controller::Helper::ParseFilter>
160 methods in conjunction with the L<SL::Controller::Helper::GetModels> style of
161 plugins. Additional filters can be defined in the database models and filtering
162 can be reduced to a minimum of work.
164 This plugin can be combined with L<SL::Controller::Sorted> and
165 L<SL::Controller::Paginated> for filtered, sorted and paginated lists.
167 The controller has to provive information where to look for filter information
168 at compile time. This call is L<make_filtered>.
170 The underlying functionality that enables the use of more than just
171 the paginate helper is provided by the controller helper
172 C<GetModels>. See the documentation for L<SL::Controller::Sorted> for
173 more information on it.
175 =head1 PACKAGE FUNCTIONS
179 =item C<make_filtered %filter_spec>
181 This function must be called by a controller at compile time. It is
182 uesd to set the various parameters required for this helper to do its
185 Careful: If you want to use this in conjunction with
186 L<SL:Controller::Helper::Paginated>, you need to call C<make_filtered> first,
187 or the paginating will not get all the relevant information to estimate the
188 number of pages correctly. To ensure this does not happen, this module will
189 croak when it detects such a scenario.
191 The hash C<%filter_spec> can include the following parameters:
197 Optional. A string: the name of the Rose database model that is used
198 as a default in certain cases. If this parameter is missing then it is
199 derived from the controller's package (e.g. for the controller
200 C<SL::Controller::BackgroundJobHistory> the C<MODEL> would default to
201 C<BackgroundJobHistory>).
203 =item * C<FORM_PARAMS>
205 Optional. Indicates a key in C<$::form> to be used as filter.
207 Defaults to the values C<filter> if missing.
209 =item * C<LAUNDER_TO>
211 Option. Indicates a target for laundered filter arguments in the controller.
212 Can be set to C<undef> to disable laundering, and can be set to method named or
213 hash keys of the controller. In the latter case the laundered structure will be
216 Defaults to inplace laundering which is not normally settable.
220 Optional. An array reference containing a list of action names for
221 which the paginate parameters should be saved. If missing or empty then
222 all actions invoked on the controller are monitored.
228 =head1 INSTANCE FUNCTIONS
230 These functions are called on a controller instance.
234 =item C<get_current_filter_params>
236 Returns a hash to be used in manager C<get_all> calls or to be passed on to
237 GetModels. Will only work if the get_models chain has been called at least
238 once, because only then the full parameters can get parsed and stored. Will
241 =item C<disable_filtering>
243 Disable filtering for the duration of the current action. Can be used
244 when using the attribute C<ONLY> to L<make_filtered> does not
255 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>