weitere umstrukturierung
authorSven Schöling <s.schoeling@linet-services.de>
Wed, 18 Sep 2013 12:48:42 +0000 (14:48 +0200)
committerSven Schöling <s.schoeling@linet-services.de>
Mon, 14 Oct 2013 09:56:11 +0000 (11:56 +0200)
SL/Controller/DeliveryPlan.pm
SL/Controller/Helper/GetModels.pm
SL/Controller/Helper/GetModels/Base.pm
SL/Controller/Helper/GetModels/Filtered.pm
SL/Controller/Helper/GetModels/Paginated.pm
SL/Controller/Helper/GetModels/Sorted.pm

index 7d394be..f5d5b4e 100644 (file)
@@ -16,32 +16,6 @@ use Rose::Object::MakeMethods::Generic (
 
 __PACKAGE__->run_before(sub { $::auth->assert('sales_order_edit'); });
 
-#__PACKAGE__->make_filtered(
-#  MODEL             => 'OrderItem',
-#  LAUNDER_TO        => 'filter'
-#);
-#__PACKAGE__->make_paginated(
-#  MODEL         => 'OrderItem',
-#  ONLY          => [ qw(list) ],
-#);
-#
-#__PACKAGE__->make_sorted(
-#  MODEL             => 'OrderItem',
-#  ONLY              => [ qw(list) ],
-#
-#  DEFAULT_BY        => 'reqdate',
-#  DEFAULT_DIR       => 1,
-#
-#  reqdate           => t8('Reqdate'),
-#  description       => t8('Description'),
-#  partnumber        => t8('Part Number'),
-#  qty               => t8('Qty'),
-#  shipped_qty       => t8('shipped'),
-#  not_shipped_qty   => t8('not shipped'),
-#  ordnumber         => t8('Order'),
-#  customer          => t8('Customer'),
-#);
-
 my %sort_columns = (
   reqdate           => t8('Reqdate'),
   description       => t8('Description'),
@@ -129,10 +103,10 @@ sub action_list {
   my ($self) = @_;
 
   $self->make_filter_summary;
+  $self->prepare_report;
 
   my $orderitems = $self->models->get;
 
-  $self->prepare_report;
   $self->report_generator_list_objects(report => $self->{report}, objects => $orderitems);
 }
 
@@ -164,6 +138,8 @@ sub prepare_report {
 
   $column_defs{$_}->{text} = $sort_columns{$_} for keys %column_defs;
 
+  $self->models->disable_plugin('paginated') if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
+  $self->models->finalize; # for filter laundering
   $report->set_options(
     std_column_visibility => 1,
     controller_class      => 'DeliveryPlan',
@@ -179,9 +155,7 @@ sub prepare_report {
   $report->set_column_order(@columns);
   $report->set_export_options(qw(list filter));
   $report->set_options_from_form;
-  $self->models->sorted->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable);
-
-  $self->models->paginated->disable_pagination if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
+  $self->models->set_report_generator_sort_options(report => $report, sortable_columns => \@sortable);
 }
 
 sub make_filter_summary {
@@ -223,7 +197,7 @@ sub init_models {
 
   SL::Controller::Helper::GetModels->new(
     controller => $self,
-    model  => 'OrderItem', # defaults to controller
+    model  => 'OrderItem',
     filtered => {
       launder_to => 'filter',
     },
index ae9810b..054bd0b 100644 (file)
@@ -7,46 +7,107 @@ 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) ],
-  'scalar --get_set_init' => [ qw(handlers) ],
+  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 = {};
+
+# official interface
+
+sub get {
+  my ($self) = @_;
+  my %params = $self->finalize;
+  %params = $self->_run_handlers('get_models', %params);
+
+  return $self->manager->get_all(%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');
+  $self->$plugin->disabled(1);
+}
+
+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) = @_;
 
-#  for my $plugin (qw(filtered sorted paginated)) {
-#    next unless $params{$plugin};
-#    $self->${ \"make_$plugin" }(%{ delete $params{$plugin} || {} });
-#  }
-#
   # 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;
-    $self->$plugin($plugin_class->new(%$spec, get_models => $self));
+    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);
+
+  return %params;
 }
 
 sub register_handlers {
   my ($self, %additional_handlers) = @_;
 
-#  my $only        = delete($additional_handlers{ONLY}) || [];
-#  $only           = [ $only ] if !ref $only;
-#  my %hook_params = @{ $only } ? ( only => $only ) : ();
-
   my $handlers    = $self->handlers;
   map { push @{ $handlers->{$_} }, $additional_handlers{$_} if $additional_handlers{$_} } keys %$handlers;
 }
 
+# TODO fix this
 sub get_models_url_params {
   my ($class, $sub_name_or_code) = @_;
 
@@ -71,26 +132,6 @@ sub get_callback {
   return $self->controller->url_for(%default_params, %override_params);
 }
 
-sub get {
-  my ($self, %params) = @_;
-
-  push @{ $params{query}        ||= [] }, @{ $self->query || [] };
-  push @{ $params{with_objects} ||= [] }, @{ $self->with_objects || [] };
-
-  %params                      = $self->_run_handlers('get_models', %params);
-
-  return $self->manager->get_all(%params);
-}
-
-sub get_paginate_args {
-  my ($self, %params) = @_;
-
-  push @{ $params{query}        ||= [] }, @{ $self->query || [] };
-  push @{ $params{with_objects} ||= [] }, @{ $self->with_objects || [] };
-
-  $self->paginated->get_current_paginate_params(%params);
-}
-
 sub manager {
   die "No 'model' to work on" unless $_[0]->model;
   "SL::DB::Manager::" . $_[0]->model;
@@ -123,6 +164,10 @@ sub init_handlers {
   }
 }
 
+sub init_source {
+  $::form
+}
+
 1;
 __END__
 
index 3d28de5..97aa84d 100644 (file)
@@ -4,11 +4,15 @@ use strict;
 use parent 'Rose::Object';
 use Scalar::Util qw(weaken);
 
-
 use Rose::Object::MakeMethods::Generic (
-  scalar => [ qw(get_models) ],
+  scalar => [ qw(get_models disabled finalized) ],
 );
 
+# phase stubs
+sub read_params { die 'implement me' }
+
+sub finalize { die 'implement me' }
+
 sub set_get_models {
   $_[0]->get_models($_[1]);
 
@@ -23,7 +27,19 @@ sub merge_args {
     $final_args->{$field} = [ map { @{ $_->{$field} || [] } } @args ];
   }
 
+  for my $field (qw(page per_page sort_by sort_dir )) {
+    for my $arg (@args) {
+      next unless defined $_->{$field};
+      $final_args->{$field} //= $_->{$field};
+    }
+  }
+
   return %$final_args;
 }
 
+sub is_enabled {
+  my ($self) = @_;
+  return !$self->disabled;
+}
+
 1;
index 3374471..c89d44d 100644 (file)
@@ -8,7 +8,7 @@ use SL::Controller::Helper::ParseFilter ();
 use List::MoreUtils qw(uniq);
 
 use Rose::Object::MakeMethods::Generic (
-  scalar => [ qw(disabled filter_args filter_params) ],
+  scalar => [ qw(filter_args filter_params orig_filter) ],
   'scalar --get_set_init' => [ qw(form_params launder_to) ],
 );
 
@@ -26,20 +26,15 @@ sub init {
   # $::lxdebug->dump(0, "CONSPEC", \%specs);
 }
 
-sub get_current_filter_params {
-  my ($self)   = @_;
+sub read_params {
+  my ($self, %params)   = @_;
 
-  return $self->filter_params if $self->filter_params;
+  return %{ $self->filter_params } if $self->filter_params;
+  my $source = $self->get_models->source;
 
-  require Carp;
-  Carp::confess('It seems a GetModels plugin tries to access filter params before they got calculated. Make sure your make_filtered call comes first.');
-}
+  my $filter            = $params{filter} // $source->{ $self->form_params } // {};
+  $self->orig_filter($filter);
 
-sub _make_current_filter_params {
-  my ($self, %params)   = @_;
-
-#  my $spec              = $self->get_filter_spec;
-  my $filter            = $params{filter} // $::form->{ $self->form_params } // {},
   my %filter_args       = $self->_get_filter_args;
   my %parse_filter_args = (
     class        => $self->get_models->manager,
@@ -58,19 +53,6 @@ sub _make_current_filter_params {
   my %calculated_params = SL::Controller::Helper::ParseFilter::parse_filter($filter, %parse_filter_args);
   %calculated_params = $self->merge_args(\%calculated_params, \%filter_args, \%params);
 
-#  $calculated_params{query} = [
-#    @{ $calculated_params{query} || [] },
-#    @{ $filter_args{      query} || [] },
-#    @{ $params{           query} || [] },
-#  ];
-#
-#  $calculated_params{with_objects} = [
-#    uniq
-#    @{ $calculated_params{with_objects} || [] },
-#    @{ $filter_args{      with_objects} || [] },
-#    @{ $params{           with_objects} || [] },
-#  ];
-
   if ($laundered) {
     if ($self->get_models->controller->can($self->launder_to)) {
       $self->get_models->controller->${\ $self->launder_to }($laundered);
@@ -86,9 +68,9 @@ sub _make_current_filter_params {
   return %calculated_params;
 }
 
-sub disable_filtering {
-  my ($self)               = @_;
-  $self->disabled(1);
+sub finalize {
+  my ($self, %params) = @_;
+  %params;
 }
 
 #
@@ -107,7 +89,7 @@ sub _callback_handler_for_filtered {
   my ($self, %params) = @_;
 
   if ($self->is_enabled) {
-    my ($flattened) = SL::Controller::Helper::ParseFilter::flatten($::form->{ $self->form_params }, $self->form_params);
+    my ($flattened) = SL::Controller::Helper::ParseFilter::flatten($self->orig_filter, $self->form_params);
     %params         = (%params, @{ $flattened || [] });
   }
 
@@ -122,15 +104,11 @@ sub _get_models_handler_for_filtered {
   # $::lxdebug->dump(0,  "params in get_models_for_filtered", \%params);
 
   my %filter_params;
-  %filter_params = $self->_make_current_filter_params(%params)  if $self->is_enabled;
+  %filter_params = $self->read_params(%params)  if $self->is_enabled;
 
   # $::lxdebug->dump(0, "GM handler for filtered; params nach modif (is_enabled? " . $self->is_enabled . ")", \%params);
 
-  return (%params, %filter_params);
-}
-
-sub is_enabled {
-  !$_[0]->disabled;
+  return $self->merge_args(\%params, \%filter_params);
 }
 
 sub init_form_params {
index a40acae..fc61ac5 100644 (file)
@@ -6,7 +6,7 @@ use parent 'SL::Controller::Helper::GetModels::Base';
 use List::Util qw(min);
 
 use Rose::Object::MakeMethods::Generic (
-  scalar => [ qw(disabled per_page) ],
+  scalar => [ qw(per_page form_data paginated_args calculated_params) ],
   'scalar --get_set_init' => [ qw(form_params paginate_args) ],
 );
 
@@ -26,17 +26,39 @@ sub init {
   # $::lxdebug->dump(0, "CONSPEC", \%specs);
 }
 
-sub get_current_paginate_params {
-  my ($self, %args)   = @_;
-  return () unless $self->is_enabled;
+sub read_params {
+  my ($self, %params)      = @_;
+
+  return %{ $self->form_data } if $self->form_data;
+  my $source = $self->get_models->source;
+
+  my $from_form = {
+    page            => $source->{ $self->form_params->[0] } || 1,
+    per_page        => $source->{ $self->form_params->[1] } * 1,
+  };
 
-  my %paginate_params = $self->final_params(%args);
+#  my $priv              = _priv($self);
+  $params{page}         = $from_form->{page}     unless defined $params{page};
+  $params{per_page}     = $from_form->{per_page} unless defined $params{per_page};
+
+  $params{page}         = ($params{page} * 1) || 1;
+  $params{per_page}     = ($params{per_page} * 1) || $self->per_page;
+
+  $self->form_data(\%params);
+
+  %params;
+}
+
+sub finalize {
+  my ($self, %args)   = @_;
+#  return () unless $self->is_enabled;
+  my %paginate_params = $self->read_params;
 
   # 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($self->paginate_args) eq 'CODE'       ? %{ $self->paginate_args->($self) }
                         :     $self->paginate_args  eq '__FILTER__'
-                           && $self->get_models->filtered ? %{ $self->get_models->filtered->get_current_filter_params }
+                           && $self->get_models->filtered ? $self->get_models->filtered->read_params
                         :     $self->paginate_args  ne '__FILTER__' ? do { my $sub = $self->paginate_args; %{ $self->get_models->controller->$sub() } }
                         :                                               ();
 
@@ -44,50 +66,25 @@ sub get_current_paginate_params {
 
   my $calculated_params = $self->get_models->manager->paginate(%paginate_params, args => \%args);
 
-  # $::lxdebug->dump(0, "get_current_paginate_params: ", $calculated_params);
+  $self->paginated_args(\%args);
+  $self->calculated_params($calculated_params);
 
-  return %{ $calculated_params };
+  return %args;
 }
 
-sub disable_pagination {
-  my ($self)               = @_;
-  $self->disabled(1);
-}
-
-sub final_params {
-  my ($self, %params)      = @_;
-
-  my $from_form = {
-    page            => $::form->{ $self->form_params->[0] } || 1,
-    per_page        => $::form->{ $self->form_params->[1] } * 1,
-  };
-
-#  my $priv              = _priv($self);
-  $params{page}         = $from_form->{page}     unless defined $params{page};
-  $params{per_page}     = $from_form->{per_page} unless defined $params{per_page};
-
-  $params{page}         = ($params{page} * 1) || 1;
-  $params{per_page}     = ($params{per_page} * 1) || $self->per_page;
-
-  %params;
+sub get_current_paginate_params {
+  my ($self, %args)   = @_;
+  return () unless $self->is_enabled;
+  %{ $self->calculated_params };
 }
 
 #
 # private functions
 #
 
-sub init_form_params {
-  [ qw(page per_page) ]
-}
-
-sub init_paginate_args {
-  '__FILTER__'
-}
-
 sub _callback_handler_for_paginated {
   my ($self, %params) = @_;
-  my %form_params = $self->final_params;
-#  my $priv            = _priv($self);
+  my %form_params = $self->read_params;
 
   if ($self->is_enabled && $form_params{page}) {
     $params{ $self->form_params->[0] } = $form_params{page};
@@ -102,16 +99,18 @@ sub _callback_handler_for_paginated {
 sub _get_models_handler_for_paginated {
   my ($self, %params)    = @_;
 
-  $self->get_models->manager->paginate($self->final_params, args => \%params) if $self->is_enabled;
+  $self->get_models->manager->paginate(%{ $self->calculated_params }, args => \%params) if $self->is_enabled;
 
   # $::lxdebug->dump(0, "GM handler for paginated; params nach modif (is_enabled? " . _is_enabled($self) . ")", \%params);
-
   return %params;
 }
 
-sub is_enabled {
-  my ($self) = @_;
-  return !$self->disabled;
+sub init_form_params {
+  [ qw(page per_page) ]
+}
+
+sub init_paginate_args {
+  '__FILTER__'
 }
 
 1;
index 9e133b8..c154d75 100644 (file)
@@ -7,7 +7,7 @@ use Carp;
 use List::MoreUtils qw(uniq);
 
 use Rose::Object::MakeMethods::Generic (
-  scalar => [ qw(by dir specs) ],
+  scalar => [ qw(by dir specs form_data) ],
   'scalar --get_set_init' => [ qw(form_params) ],
 );
 
@@ -43,16 +43,19 @@ sub init {
 #   $::lxdebug->dump(0, "CONSPEC", \%specs);
 }
 
-sub get_current_sort_params {
+sub read_params {
   my ($self, %params) = @_;
 
+  return %{ $self->form_data } if $self->form_data;
+
   my %sort_params;
   my ($by, $dir) = @{ $self->form_params };
+  my $source = $self->get_models->source;
 
-  if ($::form->{ $by }) {
+  if ($source->{ $by }) {
     %sort_params = (
-      sort_by  => $::form->{$by},
-      sort_dir => defined($::form->{$dir}) ? $::form->{$dir} * 1 : undef,
+      sort_by  => $source->{$by},
+      sort_dir => defined($source->{$dir}) ? $source->{$dir} * 1 : undef,
     );
   } elsif (!$self->by) {
     %sort_params = %params;
@@ -63,15 +66,22 @@ sub get_current_sort_params {
     );
   }
 
+  $self->form_data(\%sort_params);
+
   return %sort_params;
 }
 
+sub finalize {
+  my ($self, %params) = @_;
+  %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;
+  my %current_sort_params = $self->read_params;
 
   foreach my $col (@{ $params{sortable_columns} }) {
     $params{report}->{columns}->{$col}->{link} = $self->get_models->get_callback(
@@ -96,7 +106,7 @@ sub set_report_generator_sort_options {
 
 sub _callback_handler_for_sorted {
   my ($self, %params) = @_;
-  my %spec = $self->get_current_sort_params;
+  my %spec = $self->read_params;
 
   if ($spec{sort_by}) {
     $params{ $self->form_params->[0] } = $spec{sort_by};
@@ -111,7 +121,7 @@ sub _callback_handler_for_sorted {
 sub _get_models_handler_for_sorted {
   my ($self, %params) = @_;
 
-  my %sort_params     = $self->get_current_sort_params;
+  my %sort_params     = $self->read_params;
   my $sort_spec       = $self->specs->{ $sort_params{sort_by} };
 
   $params{sort_by}    = "SL::DB::Manager::$sort_spec->{model}"->make_sort_string(sort_by => $sort_spec->{model_column}, sort_dir => $sort_params{sort_dir});