X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FHelper%2FSorted.pm;h=2bdc51b6b6ec067031552363acdcb50dafe0fb63;hb=2f4fdf754423ff264d4570c1f396456f7f7ea90c;hp=817f80319fb6015156868b8fad333e175589d5a7;hpb=481e3f934e08d79a35597e01e0c02bb9931ef4a7;p=kivitendo-erp.git diff --git a/SL/Controller/Helper/Sorted.pm b/SL/Controller/Helper/Sorted.pm index 817f80319..2bdc51b6b 100644 --- a/SL/Controller/Helper/Sorted.pm +++ b/SL/Controller/Helper/Sorted.pm @@ -2,33 +2,40 @@ package SL::Controller::Helper::Sorted; use strict; +use Carp; +use List::MoreUtils qw(uniq); + use Exporter qw(import); -our @EXPORT = qw(make_sorted get_sort_spec get_current_sort_params _save_current_sort_params _get_models_handler_for_sorted _callback_handler_for_sorted); +our @EXPORT = qw(make_sorted get_sort_spec get_current_sort_params set_report_generator_sort_options + _save_current_sort_params _get_models_handler_for_sorted _callback_handler_for_sorted); + +use constant PRIV => '__sortedhelperpriv'; -my ($controller_sort_spec, $current_sort_by, $current_sort_dir); +my %controller_sort_spec; sub make_sorted { my ($class, %specs) = @_; - $specs{MODEL} ||= $class->_controller_name; + $specs{MODEL} ||= $class->controller_name; $specs{MODEL} =~ s{ ^ SL::DB:: (?: .* :: )? }{}x; while (my ($column, $spec) = each %specs) { next if $column =~ m/^[A-Z_]+$/; - $spec = $specs{$column} = { title => $spec } if !ref $spec; + $spec = $specs{$column} = { title => $spec } if (ref($spec) || '') ne 'HASH'; $spec->{model} ||= $specs{MODEL}; $spec->{model_column} ||= $column; } - $specs{DEFAULT_DIR} = $specs{DEFAULT_DIR} || !defined($specs{DEFAULT_DIR}) ? 1 : 0; - $specs{DEFAULT_BY} ||= { "SL::DB::Manager::$specs{MODEL}"->_sort_spec }->{default}->[0]; + my %model_sort_spec = "SL::DB::Manager::$specs{MODEL}"->_sort_spec; + $specs{DEFAULT_DIR} = $specs{DEFAULT_DIR} ? 1 : defined($specs{DEFAULT_DIR}) ? $specs{DEFAULT_DIR} * 1 : $model_sort_spec{default}->[1]; + $specs{DEFAULT_BY} ||= $model_sort_spec{default}->[0]; $specs{FORM_PARAMS} ||= [ qw(sort_by sort_dir) ]; $specs{ONLY} ||= []; $specs{ONLY} = [ $specs{ONLY} ] if !ref $specs{ONLY}; - $controller_sort_spec = \%specs; + $controller_sort_spec{$class} = \%specs; my %hook_params = @{ $specs{ONLY} } ? ( only => $specs{ONLY} ) : (); $class->run_before('_save_current_sort_params', %hook_params); @@ -46,7 +53,7 @@ sub make_sorted { sub get_sort_spec { my ($class_or_self) = @_; - return $controller_sort_spec; + return $controller_sort_spec{ref($class_or_self) || $class_or_self}; } sub get_current_sort_params { @@ -55,8 +62,9 @@ sub get_current_sort_params { my $sort_spec = $self->get_sort_spec; if (!$params{sort_by}) { - $params{sort_by} = $current_sort_by; - $params{sort_dir} = $current_sort_dir; + my $priv = $self->{PRIV()} || {}; + $params{sort_by} = $priv->{by}; + $params{sort_dir} = $priv->{dir}; } my $by = $params{sort_by} || $sort_spec->{DEFAULT_BY}; @@ -68,27 +76,55 @@ sub get_current_sort_params { return %sort_params; } +sub set_report_generator_sort_options { + my ($self, %params) = @_; + + $params{$_} or croak("Missing parameter '$_'") for qw(report sortable_columns); + + my %current_sort_params = $self->get_current_sort_params; + + foreach my $col (@{ $params{sortable_columns} }) { + $params{report}->{columns}->{$col}->{link} = $self->get_callback( + sort_by => $col, + sort_dir => ($current_sort_params{by} eq $col ? 1 - $current_sort_params{dir} : $current_sort_params{dir}), + ); + } + + $params{report}->set_sort_indicator($current_sort_params{by}, 1 - $current_sort_params{dir}); + + if ($params{report}->{export}) { + $params{report}->{export}->{variable_list} = [ uniq( + @{ $params{report}->{export}->{variable_list} }, + @{ $self->get_sort_spec->{FORM_PARAMS} } + )]; + } +} + # # private functions # sub _save_current_sort_params { - my ($self) = @_; + my ($self) = @_; - my $sort_spec = $self->get_sort_spec; - $current_sort_by = $::form->{ $sort_spec->{FORM_PARAMS}->[0] }; - $current_sort_dir = !!$::form->{ $sort_spec->{FORM_PARAMS}->[1] } * 1; + my $sort_spec = $self->get_sort_spec; + my $dir_idx = $sort_spec->{FORM_PARAMS}->[1]; + $self->{PRIV()} = { + by => $::form->{ $sort_spec->{FORM_PARAMS}->[0] }, + dir => defined($::form->{$dir_idx}) ? $::form->{$dir_idx} * 1 : undef, + }; - # $::lxdebug->message(0, "saving current sort params to $current_sort_by / $current_sort_dir"); + # $::lxdebug->message(0, "saving current sort params to " . $self->{PRIV()}->{by} . ' / ' . $self->{PRIV()}->{dir}); } sub _callback_handler_for_sorted { my ($self, %params) = @_; - if ($current_sort_by) { + my $priv = $self->{PRIV()} || {}; + if ($priv->{by}) { my $sort_spec = $self->get_sort_spec; - $params{ $sort_spec->{FORM_PARAMS}->[0] } = $current_sort_by; - $params{ $sort_spec->{FORM_PARAMS}->[1] } = $current_sort_dir; + $params{ $sort_spec->{FORM_PARAMS}->[0] } = $priv->{by}; + $params{ $sort_spec->{FORM_PARAMS}->[1] } = $priv->{dir}; } # $::lxdebug->dump(0, "CB handler for sorted; params nach modif:", \%params); @@ -143,7 +179,7 @@ In a controller: sub action_list { my ($self) = @_; - my $sorted_models = $self->get_sorted; + my $sorted_models = $self->get_models; $self->render('controller/list', ENTRIES => $sorted_models); } @@ -186,6 +222,9 @@ calls to e.g. C. A template on the other hand can use the method C from the layout helper module C. +This module requires that the Rose model managers use their C +helper. + The C helper hooks into the controller call to the action via a C hook. This is done so that it can remember the sort parameters that were used in the current view. @@ -207,31 +246,32 @@ that can be used for sorting (similar to database column names). The second kind are also the indexes you use in a template when calling C<[% L.sorted_table_header(...) %]>. -Control parameters include the following (all required parameters -occur first): +Control parameters include the following: =over 4 +=item * C + +Optional. A string: the name of the Rose database model that is used +as a default in certain cases. If this parameter is missing then it is +derived from the controller's package (e.g. for the controller +C the C would default to +C). + =item * C -Required. A string: the index to sort by if the user hasn't clicked on +Optional. A string: the index to sort by if the user hasn't clicked on any column yet (meaning: if the C<$::form> parameters for sorting do not contain a valid index). +Defaults to the underlying database model's default sort column name. + =item * C Optional. Default sort direction (ascending for trueish values, descrending for falsish values). -Defaults to C<1> if missing. - -=item * C - -Optional. A string: the name of the Rose database model that is used -as a default in certain cases. If this parameter is missing then it is -derived from the controller's package (e.g. for the controller -C the C would default to -C). +Defaults to the underlying database model's default sort direction. =item * C @@ -266,6 +306,9 @@ Required. A user-displayable title to be used by functions like the layout helper's C. Does not have a default value. +Note that this string must be the untranslated English version of the +string. The titles will be translated whenever they're requested. + =item * C Optional. The name of a Rose database model this sort index refers @@ -306,6 +349,31 @@ Returns a hash reference to the sort spec structure given in the call to L after normalization (hash reference construction, applying default parameters etc). +=item C + +This function does three things with an instance of +L: + +=over 4 + +=item 1. it sets the sort indicator, + +=item 2. it sets the the links for those column headers that are +sortable and + +=item 3. it adds the C fields to the list of variables in +the report generator's export options. + +=back + +The report generator instance must be passed as the parameter +C. The parameter C must be an array +reference of column names that are sortable. + +The report generator instance must already have its columns and export +options set via calls to its L and +L functions. + =back =head1 BUGS