X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/blobdiff_plain/36b5dead243946c4447e9a854ebd67e613853f88..95f9f85a003a94c70a8daaaef7aef91522050fa6:/SL/Controller/Helper/GetModels.pm diff --git a/SL/Controller/Helper/GetModels.pm b/SL/Controller/Helper/GetModels.pm index 00ef31017..a4cd973b8 100644 --- a/SL/Controller/Helper/GetModels.pm +++ b/SL/Controller/Helper/GetModels.pm @@ -2,42 +2,139 @@ package SL::Controller::Helper::GetModels; use strict; -use Exporter qw(import); -our @EXPORT = qw(get_callback get_models); +use parent 'Rose::Object'; +use SL::Controller::Helper::GetModels::Filtered; +use SL::Controller::Helper::GetModels::Sorted; +use SL::Controller::Helper::GetModels::Paginated; + +use Scalar::Util qw(weaken); + +use Rose::Object::MakeMethods::Generic ( + scalar => [ qw(controller model query with_objects filtered sorted paginated finalized final_params) ], + 'scalar --get_set_init' => [ qw(handlers source) ], + array => [ qw(plugins) ], +); use constant PRIV => '__getmodelshelperpriv'; -my %registered_handlers = ( callback => [], get_models => [] ); -sub register_get_models_handlers { - my ($class, %additional_handlers) = @_; +# official interface + +sub get { + my ($self) = @_; + my %params = $self->finalize; - my $only = delete($additional_handlers{ONLY}) || []; - $only = [ $only ] if !ref $only; - my %hook_params = @{ $only } ? ( only => $only ) : (); + return $self->manager->get_all(%params); +} - $class->run_before(sub { $_[0]->{PRIV()} = { current_action => $_[1] }; }, %hook_params); +sub disable_plugin { + my ($self, $plugin) = @_; + die 'cannot change internal state after finalize was called' if $self->finalized; + die 'unsupported plugin' unless $self->can($plugin) && $self->$plugin && $self->$plugin->isa('SL::Controller::Helper::GetModels::Base'); - map { push @{ $registered_handlers{$_} }, $additional_handlers{$_} if $additional_handlers{$_} } keys %registered_handlers; + $self->$plugin->disabled(1); } -sub get_callback { - my ($self, %override_params) = @_; +sub enable_plugin { + my ($self, $plugin) = @_; + die 'cannot change internal state after finalize was called' if $self->finalized; + die 'unsupported plugin' unless $self->can($plugin) && $self->$plugin && $self->$plugin->isa('SL::Controller::Helper::GetModels::Base'); + $self->$plugin->disabled(0); +} + +sub is_enabled_plugin { + my ($self, $plugin) = @_; + die 'unsupported plugin' unless $self->can($plugin) && $self->$plugin && $self->$plugin->isa('SL::Controller::Helper::GetModels::Base'); + $self->$plugin->is_enabled; +} + +# TODO: get better delegation +sub set_report_generator_sort_options { + my ($self, %params) = @_; + $self->finalize; + + $self->sorted->set_report_generator_sort_options(%params); +} + +sub get_paginate_args { + my ($self) = @_; + my %params = $self->finalize; + + $self->paginated->get_current_paginate_params(%params); +} + +sub init { + my ($self, %params) = @_; + + # TODO: default model + $self->model(delete $params{model}); + + my @plugins; + for my $plugin (qw(filtered sorted paginated)) { + next unless my $spec = delete $params{$plugin} // {}; + my $plugin_class = "SL::Controller::Helper::GetModels::" . ucfirst $plugin; + push @plugins, $self->$plugin($plugin_class->new(%$spec, get_models => $self)); + } + $self->plugins(@plugins); + + $self->SUPER::init(%params); + + $_->read_params for $self->plugins; + + weaken $self->controller if $self->controller; +} + +sub finalize { + my ($self, %params) = @_; + + return %{ $self->final_params } if $self->finalized; + + push @{ $params{query} ||= [] }, @{ $self->query || [] }; + push @{ $params{with_objects} ||= [] }, @{ $self->with_objects || [] }; + + %params = $_->finalize(%params) for $self->plugins; + + $self->finalized(1); + $self->final_params(\%params); - my %default_params = _run_handlers($self, 'callback', action => ($self->{PRIV()} || {})->{current_action}); + return %params; +} + +sub register_handlers { + my ($self, %additional_handlers) = @_; + + my $handlers = $self->handlers; + map { push @{ $handlers->{$_} }, $additional_handlers{$_} if $additional_handlers{$_} } keys %$handlers; +} - return $self->url_for(%default_params, %override_params); +# TODO fix this +sub get_models_url_params { + my ($class, $sub_name_or_code) = @_; + + my $code = (ref($sub_name_or_code) || '') eq 'CODE' ? $sub_name_or_code : sub { shift->$sub_name_or_code(@_) }; + my $callback = sub { + my ($self, %params) = @_; + my @additional_params = $code->($self); + return ( + %params, + (scalar(@additional_params) == 1) && (ref($additional_params[0]) eq 'HASH') ? %{ $additional_params[0] } : @additional_params, + ); + }; + + push @{ _registered_handlers($class)->{callback} }, $callback; } -sub get_models { +sub get_callback { my ($self, %override_params) = @_; - my %default_params = _run_handlers($self, 'get_models'); + my %default_params = $self->_run_handlers('callback', action => $self->controller->action_name); - my %params = (%default_params, %override_params); - my $model = delete($params{model}) || die "No 'model' to work on"; + return $self->controller->url_for(%default_params, %override_params); +} - return "SL::DB::Manager::${model}"->get_all(%params); +sub manager { + die "No 'model' to work on" unless $_[0]->model; + "SL::DB::Manager::" . $_[0]->model; } # @@ -47,7 +144,7 @@ sub get_models { sub _run_handlers { my ($self, $handler_type, %params) = @_; - foreach my $sub (@{ $registered_handlers{$handler_type} }) { + foreach my $sub (@{ $self->handlers->{$handler_type} }) { if (ref $sub eq 'CODE') { %params = $sub->($self, %params); } elsif ($self->can($sub)) { @@ -60,6 +157,16 @@ sub _run_handlers { return %params; } +sub init_handlers { + { + callback => [], + } +} + +sub init_source { + $::form +} + 1; __END__ @@ -102,6 +209,19 @@ in L. =over 4 +=item C + +Register one of the controller's subs to be called whenever an URL has +to be generated (e.g. for sort and pagination links). This is a way +for the controller to add additional parameters to the URL (e.g. for +filter parameters). + +The C<$sub> parameter can be either a code reference or the name of +one of the controller's functions. + +The value returned by this C<$sub> must be either a single hash +reference or a hash of key/value pairs to add to the URL. + =item C This function should only be called from other controller helpers like