Revision 78bceada
Von Sven Schöling vor mehr als 11 Jahren hinzugefügt
SL/Controller/Helper/GetModels.pm | ||
---|---|---|
sub init {
|
||
my ($self, %params) = @_;
|
||
|
||
# TODO: default model
|
||
$self->model(delete $params{model});
|
||
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)) {
|
||
... | ... | |
map { push @{ $handlers->{$_} }, $additional_handlers{$_} if $additional_handlers{$_} } keys %$handlers;
|
||
}
|
||
|
||
# TODO fix this
|
||
sub get_models_url_params {
|
||
my ($class, $sub_name_or_code) = @_;
|
||
my ($self, $sub_name_or_code) = @_;
|
||
|
||
my $code = (ref($sub_name_or_code) || '') eq 'CODE' ? $sub_name_or_code : sub { shift->$sub_name_or_code(@_) };
|
||
my $code = (ref($sub_name_or_code) || '') eq 'CODE' ? $sub_name_or_code : sub { shift->controller->$sub_name_or_code(@_) };
|
||
my $callback = sub {
|
||
my ($self, %params) = @_;
|
||
my @additional_params = $code->($self);
|
||
... | ... | |
);
|
||
};
|
||
|
||
push @{ _registered_handlers($class)->{callback} }, $callback;
|
||
$self->registere_handlers('callback' => $callback);
|
||
}
|
||
|
||
sub get_callback {
|
||
... | ... | |
|
||
=head1 NAME
|
||
|
||
SL::Controller::Helper::GetModels - Base mixin for controller helpers
|
||
dealing with semi-automatic handling of sorting and paginating lists
|
||
SL::Controller::Helper::GetModels - Base class for a the GetModels system.
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
For a proper synopsis see L<SL::Controller::Helper::Sorted>.
|
||
In controller:
|
||
|
||
=head1 OVERVIEW
|
||
use SL::Controller::Helper::GetModels;
|
||
|
||
my $get_models = SL::Controller::Helper::GetModels->new(
|
||
controller => $self,
|
||
);
|
||
|
||
For a generic overview see L<SL::Controller::Helper::Sorted>.
|
||
my $models = $self->get_models->get;
|
||
|
||
=head1 OVERVIEW
|
||
|
||
This base module is the interface between a controller and specialized
|
||
helper modules that handle things like sorting and paginating. The
|
||
specialized helpers register themselves with this module via a call to
|
||
L<register_get_models_handlers> during compilation time (e.g. in the
|
||
case of C<Sorted> this happens when the controller calls
|
||
L<SL::Controller::Helper::Sorted::make_sorted>).
|
||
Building a CRUD controller would be easy, were it not for those stupid
|
||
list actions. People unreasonable expect stuff like filtering, sorting,
|
||
paginating, exporting etc simply to work. Well, lets try to make it simply work
|
||
a little.
|
||
|
||
A controller will later usually call the L<get_models>
|
||
function. Templates will call the L<get_callback> function. Both
|
||
functions run the registered handlers handing over control to the
|
||
specialized helpers so that they may inject their parameters into the
|
||
call chain.
|
||
This class is a proxy between a controller and specialized
|
||
helper modules that handle these things (sorting, paginating etc) and gives you
|
||
the means to retrieve the information when needed to display sort headers or
|
||
paginating footers.
|
||
|
||
The C<GetModels> helper hooks into the controller call to the action
|
||
via a C<run_before> hook. This is done so that it can remember the
|
||
action called by the user. This is used for constructing the callback
|
||
in L<get_callback>.
|
||
Information about the requested data query can be stored into the object up to
|
||
a certain point, from which on the object becomes locked and can only be
|
||
accessed for information. (Seee TODO STAGES).
|
||
|
||
=head1 PACKAGE FUNCTIONS
|
||
=head1 INTERFACE METHODS
|
||
|
||
=over 4
|
||
|
||
=item C<get_models_url_params $class, $sub>
|
||
=item new PARMAS
|
||
|
||
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).
|
||
Create a new GetModels object. Params must have at least an entry
|
||
C<controller>, other than that, see C<CONFIGURATION> for options.
|
||
|
||
The C<$sub> parameter can be either a code reference or the name of
|
||
=item get
|
||
|
||
Retrieve all models for the current configuration. Will finalize the object.
|
||
|
||
=item get_models_url_params SUB
|
||
|
||
Register a sub 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 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
|
||
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 C<register_get_models_handlers $class, %handlers>
|
||
=item get_callback
|
||
|
||
Returns a URL suitable for use as a callback parameter. It maps to the
|
||
current controller and action. All registered handlers of type
|
||
'callback' (e.g. the ones by C<Sorted> and C<Paginated>) can inject
|
||
the parameters they need so that the same list view as is currently
|
||
visible can be re-rendered.
|
||
|
||
Optional C<%params> passed to this function may override any parameter
|
||
set by the registered handlers.
|
||
|
||
=item enable_plugin PLUGIN
|
||
|
||
=item disable_plugin PLUGIN
|
||
|
||
=item is_enabled_plugin PLUGIN
|
||
|
||
This function should only be called from other controller helpers like
|
||
C<Sorted> or C<Paginated>. It is not exported and must therefore be
|
||
called its full name. The first parameter C<$class> must be the actual
|
||
controller's class name.
|
||
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.
|
||
|
||
If C<%handlers> contains a key C<ONLY> then it is passed to the hook
|
||
registration in L<SL::Controller::Base::run_before>.
|
||
Must not be finalized to use this.
|
||
|
||
The C<%handlers> register callback functions in the specialized
|
||
controller helpers that are called during invocation of
|
||
L<get_callback> or L<get_models>. Possible keys are C<callback> and
|
||
C<models>.
|
||
=item finalize
|
||
|
||
Each handler (the value in the hash) can be either a code reference
|
||
(in which case it is called directly) or the name of an instance
|
||
function callable on a controller instance. In both cases the handler
|
||
receives a hash of parameters built during this very call to
|
||
L<get_callback> or L<get_models> respectively. The handler's return
|
||
value must be the new hash to be used in calls to further handlers and
|
||
to the actual database model functions later on.
|
||
Forces finalized state. Can be used on finalized objects without error.
|
||
|
||
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
|
||
switches from configuration to finalized state.
|
||
|
||
=item source HASHREF
|
||
|
||
The source for user supplied information. Defaults to $::form. Changing it
|
||
after C<Base> phase has no effect.
|
||
|
||
=item controller CONTROLLER
|
||
|
||
A weakened link to the controller that created the GetModels object. Needed for
|
||
certain plugin methods.
|
||
|
||
=back
|
||
|
||
=head1 INSTANCE FUNCTIONS
|
||
=head1 DELEGATION METHODS
|
||
|
||
Methods delegating to C<Sorted>:
|
||
|
||
=over 4
|
||
|
||
=item C<get_callback [%params]>
|
||
=item *
|
||
|
||
Return an URL suitable for use as a callback parameter. It maps to the
|
||
current controller and action. All registered handlers of type
|
||
'callback' (e.g. the ones by C<Sorted> and C<Paginated>) can inject
|
||
the parameters they need so that the same list view as is currently
|
||
visible can be re-rendered.
|
||
set_report_generator_sort_options
|
||
|
||
Optional C<%params> passed to this function may override any parameter
|
||
set by the registered handlers.
|
||
=item *
|
||
|
||
=item C<get_models [%params]>
|
||
get_sort_spec
|
||
|
||
Query the model manager via C<get_all> and return its result. The
|
||
parameters to C<get_all> are constructed by calling all registered
|
||
handlers of type 'models' (e.g. the ones by C<Sorted> and
|
||
C<Paginated>).
|
||
=item *
|
||
|
||
Optional C<%params> passed to this function may override any parameter
|
||
set by the registered handlers.
|
||
get_current_sort_params
|
||
|
||
=back
|
||
|
||
Methods delegating to C<Paginated>:
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
The return value is the an array reference of C<Rose> models.
|
||
get_paginate_args
|
||
|
||
=back
|
||
|
||
=head1 BUGS
|
||
=head1 STATES
|
||
|
||
Nothing here yet.
|
||
A GetModels object is in one of 3 states at any given time. Their purpose is to
|
||
make a class of bugs impossible that orginated from changing the configuration
|
||
of a GetModels object halfway during the request. This was a huge problem in
|
||
the old implementation.
|
||
|
||
=head1 AUTHOR
|
||
=over 4
|
||
|
||
=item Base
|
||
|
||
This is the state after creating a new object.
|
||
|
||
=item Init
|
||
|
||
In this state every information needed from the source ($::form) has beed 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>.
|
||
|
||
=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.
|
||
|
||
=back
|
||
|
||
|
||
=head1 CONFIGURATION
|
||
|
||
Most of the configuration will be handed to GetModels on creation via C<new>.
|
||
This is a list of accepted params.
|
||
|
||
=over 4
|
||
|
||
=item controller SELF
|
||
|
||
The creating controller. Currently this is mandatory.
|
||
|
||
=item model MODEL
|
||
|
||
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 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
|
||
will disable the plugin.
|
||
|
||
If the value is a hashref, it will be passed to the plugin C<init> method.
|
||
|
||
=item query
|
||
|
||
=item with_objects
|
||
|
||
Additional static parts for Rose to include into the final query.
|
||
|
||
=item source
|
||
|
||
Source for plugins to pull their data from. Defaults to $::form.
|
||
|
||
=back
|
||
|
||
=head1 BUGS AND CAVEATS
|
||
|
||
=over 4
|
||
|
||
=item *
|
||
|
||
Delegation is not as clean as it should be. Most of the methods rely on action
|
||
at a distance and should be moved out.
|
||
|
||
=back
|
||
|
||
=head1 AUTHORS
|
||
|
||
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
|
||
|
||
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
|
||
|
||
=cut
|
Auch abrufbar als: Unified diff
model Autoerkennung und Doku