1 package SL::Controller::Helper::GetModels::Sorted;
4 use parent 'SL::Controller::Helper::GetModels::Base';
7 use List::MoreUtils qw(uniq);
9 use Rose::Object::MakeMethods::Generic (
10 scalar => [ qw(by dir specs form_data) ],
11 'scalar --get_set_init' => [ qw(form_params) ],
15 my ($self, %specs) = @_;
17 $self->set_get_models(delete $specs{get_models});
18 my %model_sort_spec = $self->get_models->manager->_sort_spec;
20 if (my $default = delete $specs{_default}) {
21 $self->by ($default->{by});
22 $self->dir($default->{dir});
24 $self->by ($model_sort_spec{default}[0]);
25 $self->dir($model_sort_spec{default}[1]);
28 while (my ($column, $spec) = each %specs) {
29 next if $column =~ m/^[A-Z_]+$/;
31 $spec = $specs{$column} = { title => $spec } if (ref($spec) || '') ne 'HASH';
33 $spec->{model} ||= $self->get_models->model;
34 $spec->{model_column} ||= $column;
36 $self->specs(\%specs);
38 $self->get_models->register_handlers(
39 callback => sub { shift; $self->_callback_handler_for_sorted(@_) },
42 # $::lxdebug->dump(0, "CONSPEC", \%specs);
46 my ($self, %params) = @_;
48 return %{ $self->form_data } if $self->form_data;
51 my ($by, $dir) = @{ $self->form_params };
52 my $source = $self->get_models->source;
54 if ($source->{ $by }) {
56 sort_by => $source->{$by},
57 sort_dir => defined($source->{$dir}) ? $source->{$dir} * 1 : undef,
59 } elsif (!$self->by) {
60 %sort_params = %params;
64 sort_dir => $self->dir,
68 $self->form_data(\%sort_params);
74 my ($self, %params) = @_;
76 my %sort_params = $self->read_params;
77 my $sort_spec = $self->specs->{ $sort_params{sort_by} };
81 $::lxdebug->show_backtrace(1);
82 die "Unknown sort spec '$sort_params{sort_by}'";
85 $params{sort_by} = "SL::DB::Manager::$sort_spec->{model}"->make_sort_string(sort_by => $sort_spec->{model_column}, sort_dir => $sort_params{sort_dir});
90 sub set_report_generator_sort_options {
91 my ($self, %params) = @_;
93 $params{$_} or croak("Missing parameter '$_'") for qw(report sortable_columns);
95 my %current_sort_params = $self->read_params;
97 foreach my $col (@{ $params{sortable_columns} }) {
98 $params{report}->{columns}->{$col}->{link} = $self->get_models->get_callback(
100 sort_dir => ($current_sort_params{sort_by} eq $col ? 1 - $current_sort_params{sort_dir} : $current_sort_params{sort_dir}),
104 $params{report}->set_sort_indicator($current_sort_params{sort_by}, 1 - $current_sort_params{sort_dir});
106 if ($params{report}->{export}) {
107 $params{report}->{export}->{variable_list} = [ uniq(
108 @{ $params{report}->{export}->{variable_list} },
109 @{ $self->form_params }
118 sub _callback_handler_for_sorted {
119 my ($self, %params) = @_;
120 my %spec = $self->read_params;
122 if ($spec{sort_by}) {
123 $params{ $self->form_params->[0] } = $spec{sort_by};
124 $params{ $self->form_params->[1] } = $spec{sort_dir};
127 # $::lxdebug->dump(0, "CB handler for sorted; params nach modif:", \%params);
132 sub init_form_params {
133 [ qw(sort_by sort_dir) ]
145 SL::Controller::Helper::Sorted - A helper for semi-automatic handling
146 of sorting lists of database models in a controller
152 SL::Controller::Helper::GetModels->new(
159 error => $::locale->text('Error'),
160 package_name => $::locale->text('Package name'),
161 run_at => $::locale->text('Run at'),
171 <th>[% L.sortable_table_header('package_name') %]</th>
172 <th>[% L.sortable_table_header('run_at') %]</th>
173 <th>[% L.sortable_table_header('error') %]</th>
176 [% FOREACH entry = ENTRIES %]
178 <td>[% HTML.escape(entry.package_name) %]</td>
179 <td>[% HTML.escape(entry.run_at) %]</td>
180 <td>[% HTML.escape(entry.error) %]</td>
187 This C<GetModels> plugin enables controllers to display a
188 sortable list of database models with as few lines as possible.
190 For this to work the controller has to provide the information which
191 indexes are eligible for sorting etc. through it's configuration of
194 A template can then use the method C<sortable_table_header> from the layout
197 This module requires that the Rose model managers use their
198 C<SL::DB::Helper::Sorted> helper.
204 =item * C<_default HASHREF>
206 Optional. If it exists, it is expected to contain the keys C<by> and C<dir> and
207 will be used to set the default sorting if nothing is found in C<source>.
209 Defaults to the underlying database model's default.
211 =item * C<form_params>
213 Optional. An array reference with exactly two strings that name the
214 indexes in C<source> in which the sort index (the first element in
215 the array) and sort direction (the second element in the array) are
218 Defaults to the values C<sort_by> and C<sort_dir> if missing.
222 All other keys can be used for sorting. Each value to such a key can be either
223 a string or a hash reference containing certain elements. If the value is only
224 a string then such a hash reference is constructed, and the string is
225 used as the value for the C<title> key.
227 These possible elements are:
233 Required. A user-displayable title to be used by functions like the
234 layout helper's C<sortable_table_header>. Does not have a default
237 Note that this string must be the untranslated English version of the
238 string. The titles will be translated whenever they're requested.
242 Optional. The name of a Rose database model this sort index refers
243 to. If missing then the value of C<$sort_spec{MODEL}> is used.
245 =item * C<model_column>
247 Optional. The name of the Rose database model column this sort index
248 refers to. It must be one of the columns named by the model's
249 C<Sorted> helper (not to be confused with the controller's C<Sorted>
252 If missing it defaults to the key in C<%sort_spec> for which this hash
253 reference is the value.
257 =head1 INSTANCE FUNCTIONS
259 These functions are called on a C<GetModels> instance and delegating to this plugin.
263 =item C<get_sort_spec>
265 Returns a hash containing the currently active sort parameters.
267 The key C<by> contains the active sort index referring to the
268 C<%sort_spec> given by the configuration.
270 The key C<dir> is either C<1> or C<0>.
272 =item C<get_current_sort_params>
274 Returns a hash reference to the sort spec structure given in the configuration
275 after normalization (hash reference construction, applying default parameters
278 =item C<set_report_generator_sort_options %params>
280 This function does three things with an instance of
281 L<SL::ReportGenerator>:
285 =item 1. it sets the sort indicator,
287 =item 2. it sets the the links for those column headers that are
290 =item 3. it adds the C<form_params> fields to the list of variables in
291 the report generator's export options.
295 The report generator instance must be passed as the parameter
296 C<report>. The parameter C<sortable_columns> must be an array
297 reference of column names that are sortable.
299 The report generator instance must already have its columns and export
300 options set via calls to its L<SL::ReportGenerator::set_columns> and
301 L<SL::ReportGenerator::set_export_options> functions.
311 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
313 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>