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(disabled filter_args filter_params) ],
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);
29 sub get_current_filter_params {
32 return $self->filter_params if $self->filter_params;
35 Carp::confess('It seems a GetModels plugin tries to access filter params before they got calculated. Make sure your make_filtered call comes first.');
38 sub _make_current_filter_params {
39 my ($self, %params) = @_;
41 # my $spec = $self->get_filter_spec;
42 my $filter = $params{filter} // $::form->{ $self->form_params } // {},
43 my %filter_args = $self->_get_filter_args;
44 my %parse_filter_args = (
45 class => $self->get_models->manager,
46 with_objects => $params{with_objects},
49 if ($self->launder_to eq '__INPLACE__') {
51 } elsif ($self->launder_to) {
53 $parse_filter_args{launder_to} = $laundered;
55 $parse_filter_args{no_launder} = 1;
58 my %calculated_params = SL::Controller::Helper::ParseFilter::parse_filter($filter, %parse_filter_args);
59 %calculated_params = $self->merge_args(\%calculated_params, \%filter_args, \%params);
61 # $calculated_params{query} = [
62 # @{ $calculated_params{query} || [] },
63 # @{ $filter_args{ query} || [] },
64 # @{ $params{ query} || [] },
67 # $calculated_params{with_objects} = [
69 # @{ $calculated_params{with_objects} || [] },
70 # @{ $filter_args{ with_objects} || [] },
71 # @{ $params{ with_objects} || [] },
75 if ($self->get_models->controller->can($self->launder_to)) {
76 $self->get_models->controller->${\ $self->launder_to }($laundered);
78 $self->get_models->controller->{$self->launder_to} = $laundered;
82 # $::lxdebug->dump(0, "get_current_filter_params: ", \%calculated_params);
84 $self->filter_params(\%calculated_params);
86 return %calculated_params;
89 sub disable_filtering {
98 sub _get_filter_args {
99 my ($self, $spec) = @_;
101 my %filter_args = ref($self->filter_args) eq 'CODE' ? %{ $self->filter_args->($self) }
102 : $self->filter_args ? do { my $sub = $self->filter_args; %{ $self->get_models->controller->$sub() } }
106 sub _callback_handler_for_filtered {
107 my ($self, %params) = @_;
109 if ($self->is_enabled) {
110 my ($flattened) = SL::Controller::Helper::ParseFilter::flatten($::form->{ $self->form_params }, $self->form_params);
111 %params = (%params, @{ $flattened || [] });
114 # $::lxdebug->dump(0, "CB handler for filtered; params after flatten:", \%params);
119 sub _get_models_handler_for_filtered {
120 my ($self, %params) = @_;
122 # $::lxdebug->dump(0, "params in get_models_for_filtered", \%params);
125 %filter_params = $self->_make_current_filter_params(%params) if $self->is_enabled;
127 # $::lxdebug->dump(0, "GM handler for filtered; params nach modif (is_enabled? " . $self->is_enabled . ")", \%params);
129 return (%params, %filter_params);
136 sub init_form_params {
140 sub init_launder_to {
155 SL::Controller::Helper::Filtered - A helper for semi-automatic handling
156 of filtered lists of database models in a controller
162 use SL::Controller::Helper::GetModels;
163 use SL::Controller::Helper::Filtered;
165 __PACKAGE__->make_filter(
167 ONLY => [ qw(list) ],
168 FORM_PARAMS => [ qw(filter) ],
174 my $filtered_models = $self->get_models(%addition_filters);
175 $self->render('controller/list', ENTRIES => $filtered_models);
181 This helper module enables use of the L<SL::Controller::Helper::ParseFilter>
182 methods in conjunction with the L<SL::Controller::Helper::GetModels> style of
183 plugins. Additional filters can be defined in the database models and filtering
184 can be reduced to a minimum of work.
186 This plugin can be combined with L<SL::Controller::Sorted> and
187 L<SL::Controller::Paginated> for filtered, sorted and paginated lists.
189 The controller has to provive information where to look for filter information
190 at compile time. This call is L<make_filtered>.
192 The underlying functionality that enables the use of more than just
193 the paginate helper is provided by the controller helper
194 C<GetModels>. See the documentation for L<SL::Controller::Sorted> for
195 more information on it.
197 =head1 PACKAGE FUNCTIONS
201 =item C<make_filtered %filter_spec>
203 This function must be called by a controller at compile time. It is
204 uesd to set the various parameters required for this helper to do its
207 Careful: If you want to use this in conjunction with
208 L<SL:Controller::Helper::Paginated>, you need to call C<make_filtered> first,
209 or the paginating will not get all the relevant information to estimate the
210 number of pages correctly. To ensure this does not happen, this module will
211 croak when it detects such a scenario.
213 The hash C<%filter_spec> can include the following parameters:
219 Optional. A string: the name of the Rose database model that is used
220 as a default in certain cases. If this parameter is missing then it is
221 derived from the controller's package (e.g. for the controller
222 C<SL::Controller::BackgroundJobHistory> the C<MODEL> would default to
223 C<BackgroundJobHistory>).
225 =item * C<FORM_PARAMS>
227 Optional. Indicates a key in C<$::form> to be used as filter.
229 Defaults to the values C<filter> if missing.
231 =item * C<LAUNDER_TO>
233 Option. Indicates a target for laundered filter arguments in the controller.
234 Can be set to C<undef> to disable laundering, and can be set to method named or
235 hash keys of the controller. In the latter case the laundered structure will be
238 Defaults to inplace laundering which is not normally settable.
242 Optional. An array reference containing a list of action names for
243 which the paginate parameters should be saved. If missing or empty then
244 all actions invoked on the controller are monitored.
250 =head1 INSTANCE FUNCTIONS
252 These functions are called on a controller instance.
256 =item C<get_current_filter_params>
258 Returns a hash to be used in manager C<get_all> calls or to be passed on to
259 GetModels. Will only work if the get_models chain has been called at least
260 once, because only then the full parameters can get parsed and stored. Will
263 =item C<disable_filtering>
265 Disable filtering for the duration of the current action. Can be used
266 when using the attribute C<ONLY> to L<make_filtered> does not
277 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>