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} };
79 $params{sort_by} = "SL::DB::Manager::$sort_spec->{model}"->make_sort_string(sort_by => $sort_spec->{model_column}, sort_dir => $sort_params{sort_dir});
84 sub set_report_generator_sort_options {
85 my ($self, %params) = @_;
87 $params{$_} or croak("Missing parameter '$_'") for qw(report sortable_columns);
89 my %current_sort_params = $self->read_params;
91 foreach my $col (@{ $params{sortable_columns} }) {
92 $params{report}->{columns}->{$col}->{link} = $self->get_models->get_callback(
94 sort_dir => ($current_sort_params{sort_by} eq $col ? 1 - $current_sort_params{sort_dir} : $current_sort_params{sort_dir}),
98 $params{report}->set_sort_indicator($current_sort_params{sort_by}, 1 - $current_sort_params{sort_dir});
100 if ($params{report}->{export}) {
101 $params{report}->{export}->{variable_list} = [ uniq(
102 @{ $params{report}->{export}->{variable_list} },
103 @{ $self->form_params }
112 sub _callback_handler_for_sorted {
113 my ($self, %params) = @_;
114 my %spec = $self->read_params;
116 if ($spec{sort_by}) {
117 $params{ $self->form_params->[0] } = $spec{sort_by};
118 $params{ $self->form_params->[1] } = $spec{sort_dir};
121 # $::lxdebug->dump(0, "CB handler for sorted; params nach modif:", \%params);
126 sub init_form_params {
127 [ qw(sort_by sort_dir) ]
139 SL::Controller::Helper::Sorted - A helper for semi-automatic handling
140 of sorting lists of database models in a controller
146 SL::Controller::Helper::GetModels->new(
153 error => $::locale->text('Error'),
154 package_name => $::locale->text('Package name'),
155 run_at => $::locale->text('Run at'),
165 <th>[% L.sortable_table_header('package_name') %]</th>
166 <th>[% L.sortable_table_header('run_at') %]</th>
167 <th>[% L.sortable_table_header('error') %]</th>
170 [% FOREACH entry = ENTRIES %]
172 <td>[% HTML.escape(entry.package_name) %]</td>
173 <td>[% HTML.escape(entry.run_at) %]</td>
174 <td>[% HTML.escape(entry.error) %]</td>
181 This C<GetModels> plugin enables controllers to display a
182 sortable list of database models with as few lines as possible.
184 For this to work the controller has to provide the information which
185 indexes are eligible for sorting etc. through it's configuration of
188 A template can then use the method C<sortable_table_header> from the layout
191 This module requires that the Rose model managers use their
192 C<SL::DB::Helper::Sorted> helper.
198 =item * C<_default HASHREF>
200 Optional. If it exists, it is expected to contain the keys C<by> and C<dir> and
201 will be used to set the default sorting if nothing is found in C<source>.
203 Defaults to the underlying database model's default.
205 =item * C<form_params>
207 Optional. An array reference with exactly two strings that name the
208 indexes in C<source> in which the sort index (the first element in
209 the array) and sort direction (the second element in the array) are
212 Defaults to the values C<sort_by> and C<sort_dir> if missing.
216 All other keys can be used for sorting. Each value to such a key can be either
217 a string or a hash reference containing certain elements. If the value is only
218 a string then such a hash reference is constructed, and the string is
219 used as the value for the C<title> key.
221 These possible elements are:
227 Required. A user-displayable title to be used by functions like the
228 layout helper's C<sortable_table_header>. Does not have a default
231 Note that this string must be the untranslated English version of the
232 string. The titles will be translated whenever they're requested.
236 Optional. The name of a Rose database model this sort index refers
237 to. If missing then the value of C<$sort_spec{MODEL}> is used.
239 =item * C<model_column>
241 Optional. The name of the Rose database model column this sort index
242 refers to. It must be one of the columns named by the model's
243 C<Sorted> helper (not to be confused with the controller's C<Sorted>
246 If missing it defaults to the key in C<%sort_spec> for which this hash
247 reference is the value.
251 =head1 INSTANCE FUNCTIONS
253 These functions are called on a C<GetModels> instance and delegating to this plugin.
257 =item C<get_sort_spec>
259 Returns a hash containing the currently active sort parameters.
261 The key C<by> contains the active sort index referring to the
262 C<%sort_spec> given by the configuration.
264 The key C<dir> is either C<1> or C<0>.
266 =item C<get_current_sort_params>
268 Returns a hash reference to the sort spec structure given in the configuration
269 after normalization (hash reference construction, applying default parameters
272 =item C<set_report_generator_sort_options %params>
274 This function does three things with an instance of
275 L<SL::ReportGenerator>:
279 =item 1. it sets the sort indicator,
281 =item 2. it sets the the links for those column headers that are
284 =item 3. it adds the C<form_params> fields to the list of variables in
285 the report generator's export options.
289 The report generator instance must be passed as the parameter
290 C<report>. The parameter C<sortable_columns> must be an array
291 reference of column names that are sortable.
293 The report generator instance must already have its columns and export
294 options set via calls to its L<SL::ReportGenerator::set_columns> and
295 L<SL::ReportGenerator::set_export_options> functions.
305 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
307 Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>