X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FController%2FHelper%2FPaginated.pm;h=0db285f1e0106ee04eaf8529a17e1fef3c25c7f9;hb=0ca85e095eb0729d30e2d370f0931983b60eeeab;hp=f0d617d3174160ac5452349c090fd3d88cebf160;hpb=ef32afedff7750a5ef937bad68d7fde5672d5d8a;p=kivitendo-erp.git diff --git a/SL/Controller/Helper/Paginated.pm b/SL/Controller/Helper/Paginated.pm index f0d617d31..0db285f1e 100644 --- a/SL/Controller/Helper/Paginated.pm +++ b/SL/Controller/Helper/Paginated.pm @@ -3,23 +3,29 @@ package SL::Controller::Helper::Paginated; use strict; use Exporter qw(import); -our @EXPORT = qw(make_paginated get_paginate_spec get_current_paginate_params _save_current_paginate_params _get_models_handler_for_paginated _callback_handler_for_paginated); +our @EXPORT = qw(make_paginated get_paginate_spec get_current_paginate_params _save_current_paginate_params _get_models_handler_for_paginated _callback_handler_for_paginated disable_pagination); -my ($controller_paginate_spec, $current_page, $current_per_page); +use constant PRIV => '__paginatedhelper_priv'; + +use List::Util qw(min); + +my %controller_paginate_spec; sub make_paginated { - my ($class, %specs) = @_; + my ($class, %specs) = @_; - $specs{MODEL} ||= $class->_controller_name; - $specs{MODEL} =~ s{ ^ SL::DB:: (?: .* :: )? }{}x; - $specs{PER_PAGE} ||= "SL::DB::Manager::$specs{MODEL}"->default_objects_per_page; - $specs{FORM_PARAMS} ||= [ qw(page per_page) ]; - $specs{ONLY} ||= []; - $specs{ONLY} = [ $specs{ONLY} ] if !ref $specs{ONLY}; + $specs{MODEL} ||= $class->controller_name; + $specs{MODEL} =~ s{ ^ SL::DB:: (?: .* :: )? }{}x; + $specs{PER_PAGE} ||= "SL::DB::Manager::$specs{MODEL}"->default_objects_per_page; + $specs{FORM_PARAMS} ||= [ qw(page per_page) ]; + $specs{PAGINATE_ARGS} ||= '__FILTER__'; + $specs{ONLY} ||= []; + $specs{ONLY} = [ $specs{ONLY} ] if !ref $specs{ONLY}; + $specs{ONLY_MAP} = @{ $specs{ONLY} } ? { map { ($_ => 1) } @{ $specs{ONLY} } } : { '__ALL__' => 1 }; - $controller_paginate_spec = \%specs; + $controller_paginate_spec{$class} = \%specs; - my %hook_params = @{ $specs{ONLY} } ? ( only => $specs{ONLY} ) : (); + my %hook_params = @{ $specs{ONLY} } ? ( only => $specs{ONLY} ) : (); $class->run_before('_save_current_paginate_params', %hook_params); SL::Controller::Helper::GetModels::register_get_models_handlers( @@ -35,7 +41,7 @@ sub make_paginated { sub get_paginate_spec { my ($class_or_self) = @_; - return $controller_paginate_spec; + return $controller_paginate_spec{ref($class_or_self) || $class_or_self}; } sub get_current_paginate_params { @@ -43,24 +49,32 @@ sub get_current_paginate_params { my $spec = $self->get_paginate_spec; - $params{page} = $current_page unless defined $params{page}; - $params{per_page} = $current_per_page unless defined $params{per_page}; + my $priv = _priv($self); + $params{page} = $priv->{page} unless defined $params{page}; + $params{per_page} = $priv->{per_page} unless defined $params{per_page}; my %paginate_params = ( page => ($params{page} * 1) || 1, per_page => ($params{per_page} * 1) || $spec->{PER_PAGE}, ); - my $calculated_params = "SL::DB::Manager::$spec->{MODEL}"->paginate(%paginate_params, args => {}); - %paginate_params = ( - %paginate_params, - num_pages => $calculated_params->{max}, - common_pages => $calculated_params->{common}, - ); + # try to use Filtered if available and nothing else is configured, but don't + # blow up if the controller does not use Filtered + my %paginate_args = ref($spec->{PAGINATE_ARGS}) eq 'CODE' ? %{ $spec->{PAGINATE_ARGS}->($self) } + : $spec->{PAGINATE_ARGS} eq '__FILTER__' + && $self->can('get_current_filter_params') ? $self->get_current_filter_params + : $spec->{PAGINATE_ARGS} ne '__FILTER__' ? do { my $sub = $spec->{PAGINATE_ARGS}; %{ $self->$sub() } } + : (); + my $calculated_params = "SL::DB::Manager::$spec->{MODEL}"->paginate(%paginate_params, args => \%paginate_args); - # $::lxdebug->dump(0, "get_current_paginate_params: ", \%paginate_params); + # $::lxdebug->dump(0, "get_current_paginate_params: ", $calculated_params); + + return %{ $calculated_params }; +} - return %paginate_params; +sub disable_pagination { + my ($self) = @_; + _priv($self)->{disabled} = 1; } # @@ -70,20 +84,25 @@ sub get_current_paginate_params { sub _save_current_paginate_params { my ($self) = @_; + return if !_is_enabled($self); + my $paginate_spec = $self->get_paginate_spec; - $current_page = $::form->{ $paginate_spec->{FORM_PARAMS}->[0] } || 1; - $current_per_page = $::form->{ $paginate_spec->{FORM_PARAMS}->[1] } * 1; + $self->{PRIV()} = { + page => $::form->{ $paginate_spec->{FORM_PARAMS}->[0] } || 1, + per_page => $::form->{ $paginate_spec->{FORM_PARAMS}->[1] } * 1, + }; - # $::lxdebug->message(0, "saving current paginate params to $current_page / $current_per_page"); + # $::lxdebug->message(0, "saving current paginate params to " . $self->{PRIV()}->{page} . ' / ' . $self->{PRIV()}->{per_page}); } sub _callback_handler_for_paginated { my ($self, %params) = @_; + my $priv = _priv($self); - if ($current_page) { + if (_is_enabled($self) && $priv->{page}) { my $paginate_spec = $self->get_paginate_spec; - $params{ $paginate_spec->{FORM_PARAMS}->[0] } = $current_page; - $params{ $paginate_spec->{FORM_PARAMS}->[1] } = $current_per_page if $current_per_page; + $params{ $paginate_spec->{FORM_PARAMS}->[0] } = $priv->{page}; + $params{ $paginate_spec->{FORM_PARAMS}->[1] } = $priv->{per_page} if $priv->{per_page}; } # $::lxdebug->dump(0, "CB handler for paginated; params nach modif:", \%params); @@ -93,15 +112,27 @@ sub _callback_handler_for_paginated { sub _get_models_handler_for_paginated { my ($self, %params) = @_; - $params{model} ||= $self->get_paginate_spec->{MODEL}; + my $spec = $self->get_paginate_spec; + $params{model} ||= $spec->{MODEL}; - "SL::DB::Manager::$params{model}"->paginate($self->get_current_paginate_params, args => \%params); + "SL::DB::Manager::$params{model}"->paginate($self->get_current_paginate_params, args => \%params) if _is_enabled($self); - # $::lxdebug->dump(0, "GM handler for paginated; params nach modif:", \%params); + # $::lxdebug->dump(0, "GM handler for paginated; params nach modif (is_enabled? " . _is_enabled($self) . ")", \%params); return %params; } +sub _priv { + my ($self) = @_; + $self->{PRIV()} ||= {}; + return $self->{PRIV()}; +} + +sub _is_enabled { + my ($self) = @_; + return !_priv($self)->{disabled} && ($self->get_paginate_spec->{ONLY_MAP}->{$self->action_name} || $self->get_paginate_spec->{ONLY_MAP}->{'__ALL__'}); +} + 1; __END__ @@ -205,6 +236,19 @@ derived from the controller's package (e.g. for the controller C the C would default to C). +=item * C + +Optional. Either a code reference or the name of function to be called +on the controller importing this helper. + +If this funciton is given then the paginate helper calls it whenever +it has to count the total number of models for calculating the number +of pages to display. The function must return a hash reference with +elements suitable for passing to a Rose model manager's C +function. + +This can be used e.g. when filtering is used. + =item * C Optional. An integer: the number of models to return per page. @@ -272,6 +316,12 @@ Returns a hash reference to the paginate spec structure given in the call to L after normalization (hash reference construction, applying default parameters etc). +=item C + +Disable pagination for the duration of the current action. Can be used +when using the attribute C to L does not +cover all cases. + =back =head1 BUGS