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) ],
+ 'scalar --get_set_init' => [ qw(handlers source list_action additional_url_params) ],
array => [ qw(plugins) ],
);
return $self->manager->get_all(%params);
}
+sub count {
+ my ($self) = @_;
+ my %params = $self->finalize;
+
+ return $self->manager->get_all_count(%params);
+}
+
sub disable_plugin {
my ($self, $plugin) = @_;
die 'cannot change internal state after finalize was called' if $self->finalized;
my @plugins;
for my $plugin (qw(filtered sorted paginated)) {
- next unless my $spec = delete $params{$plugin} // {};
+ next if exists($params{$plugin}) && !$params{$plugin};
+
+ 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));
}
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 || [] };
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;
+}
+
sub get_models_url_params {
my ($self, $sub_name_or_code) = @_;
);
};
- $self->registere_handlers('callback' => $callback);
+ $self->register_handlers('callback' => $callback);
+}
+
+sub get_callback_params {
+ my ($self, %override_params) = @_;
+
+ my %default_params = $self->_run_handlers('callback', action => $self->list_action);
}
sub get_callback {
my ($self, %override_params) = @_;
- my %default_params = $self->_run_handlers('callback', action => $self->controller->action_name);
+ my %default_params = $self->get_callback_params(%override_params);
return $self->controller->url_for(%default_params, %override_params);
}
$::form
}
+sub init_list_action {
+ $_[0]->controller->action_name
+}
+
+sub init_additional_url_params { +{} }
+
1;
__END__
=head1 NAME
-SL::Controller::Helper::GetModels - Base class for a the GetModels system.
+SL::Controller::Helper::GetModels - Base class for the GetModels system.
=head1 SYNOPSIS
=head1 OVERVIEW
Building a CRUD controller would be easy, were it not for those stupid
-list actions. People unreasonable expect stuff like filtering, sorting,
+list actions. People unreasonably expect stuff like filtering, sorting,
paginating, exporting etc simply to work. Well, lets try to make it simply work
a little.
the means to retrieve the information when needed to display sort headers or
paginating footers.
-Information about the requested data query can be stored into the object up to
+Information about the requested data query can be stored in the object up to
a certain point, from which on the object becomes locked and can only be
-accessed for information. (Seee TODO STAGES).
+accessed for information. (See C<STATES>).
=head1 INTERFACE METHODS
=over 4
-=item new PARMAS
+=item new PARAMS
Create a new GetModels object. Params must have at least an entry
C<controller>, other than that, see C<CONFIGURATION> for options.
The value returned by C<SUB> must be either a single hash
reference or a hash of key/value pairs to add to the URL.
+=item add_additional_url_params C<%params>
+
+Sets additional parameters that will be added to each URL generated by
+this model (e.g. for pagination/sorting). This is just sugar for a
+proper call to L<get_models_url_params> with an anonymous sub adding
+those parameters.
+
=item get_callback
Returns a URL suitable for use as a callback parameter. It maps to the
Enable or disable the specified plugin. Useful to disable paginating for
exports for example. C<is_enabled_plugin> can be used to check the current
-state fo a plugin.
+state of a plugin.
Must not be finalized to use this.
Note that most higher functions will call this themselves to force a finalized
state. If you do use it it must come before any other finalizing methods, and
-will most likely function as a reminder or maintainers where your codes
+will most likely function as a reminder for maintainers where your code
switches from configuration to finalized state.
=item source HASHREF
=head1 DELEGATION METHODS
+All of these finalize.
+
Methods delegating to C<Sorted>:
=over 4
=item Init
-In this state every information needed from the source ($::form) has beed read
+In this state all the information needed from the source ($::form) has been read
and subsequent changes to the source have no effect. In the current
-implementation this will called immediately during creation, so that the return
-value of C<new> is already in state C<Init>.
+implementation this will happen during creation, so that the return value of
+C<new> is already in state C<Init>.
=item Finalized
In this state no new configuration will be accepted so that information gotten
through the various methods is consistent. Every information retrieval method
-will trigger finalizing.
+will trigger finalize.
=back
The name of the model for this GetModels instance. If none is given, the model
is inferred from the name of the controller class.
+=item list_action ACTION
+
+If callbacks are generated, use this action instead of the current action.
+Usually you can omit this. In case the reporting is done without redirecting
+from a mutating action, this is necessary to have callbacks for paginating and
+sorting point to the correct action.
+
=item sorted PARAMS
=item paginated PARAMS
=item filtered PARAMS
Configuration for plugins. If the option for any plugin is omitted, it defaults
-to enabled and configured by default. Giving a falsish value as first argument
+to enabled and is configured by default. Giving a falsish value as first argument
will disable the plugin.
-If the value is a hashref, it will be passed to the plugin C<init> method.
+If the value is a hashref, it will be passed to the plugin's C<init> method.
=item query