+ $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 get_sort_spec {
+ my ($self) = @_;
+
+ $self->sorted->specs;
+}
+
+sub get_current_sort_params {
+ my ($self) = @_;
+
+ $self->sorted->read_params;
+}
+
+sub init {
+ my ($self, %params) = @_;
+
+ my $model = delete $params{model};
+ if (!$model && $params{controller} && ref $params{controller}) {
+ $model = ref $params{controller};
+ $model =~ s/.*:://;
+ die 'Need a valid model' unless $model;
+ }
+ $self->model($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;
+
+ $self->register_handlers(callback => sub { shift; (@_, %{ $self->additional_url_params }) }) if %{ $self->additional_url_params };
+
+ 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 $handlers = $self->handlers;
+ map { push @{ $handlers->{$_} }, $additional_handlers{$_} if $additional_handlers{$_} } keys %$handlers;
+}
+
+sub add_additional_url_params {
+ my ($self, %params) = @_;
+
+ $self->additional_url_params({ %{ $self->additional_url_params }, %params });
+
+ return $self;