Revision 78bceada
Von Sven Schöling vor etwa 11 Jahren hinzugefügt
SL/Controller/Helper/GetModels.pm | ||
---|---|---|
78 | 78 |
sub init { |
79 | 79 |
my ($self, %params) = @_; |
80 | 80 |
|
81 |
# TODO: default model |
|
82 |
$self->model(delete $params{model}); |
|
81 |
my $model = delete $params{model}; |
|
82 |
if (!$model && $params{controller} && ref $params{controller}) { |
|
83 |
$model = ref $params{controller}; |
|
84 |
$model =~ s/.*:://; |
|
85 |
die 'Need a valid model' unless $model; |
|
86 |
} |
|
87 |
$self->model($model); |
|
83 | 88 |
|
84 | 89 |
my @plugins; |
85 | 90 |
for my $plugin (qw(filtered sorted paginated)) { |
... | ... | |
119 | 124 |
map { push @{ $handlers->{$_} }, $additional_handlers{$_} if $additional_handlers{$_} } keys %$handlers; |
120 | 125 |
} |
121 | 126 |
|
122 |
# TODO fix this |
|
123 | 127 |
sub get_models_url_params { |
124 |
my ($class, $sub_name_or_code) = @_;
|
|
128 |
my ($self, $sub_name_or_code) = @_;
|
|
125 | 129 |
|
126 |
my $code = (ref($sub_name_or_code) || '') eq 'CODE' ? $sub_name_or_code : sub { shift->$sub_name_or_code(@_) }; |
|
130 |
my $code = (ref($sub_name_or_code) || '') eq 'CODE' ? $sub_name_or_code : sub { shift->controller->$sub_name_or_code(@_) };
|
|
127 | 131 |
my $callback = sub { |
128 | 132 |
my ($self, %params) = @_; |
129 | 133 |
my @additional_params = $code->($self); |
... | ... | |
133 | 137 |
); |
134 | 138 |
}; |
135 | 139 |
|
136 |
push @{ _registered_handlers($class)->{callback} }, $callback;
|
|
140 |
$self->registere_handlers('callback' => $callback);
|
|
137 | 141 |
} |
138 | 142 |
|
139 | 143 |
sub get_callback { |
... | ... | |
188 | 192 |
|
189 | 193 |
=head1 NAME |
190 | 194 |
|
191 |
SL::Controller::Helper::GetModels - Base mixin for controller helpers |
|
192 |
dealing with semi-automatic handling of sorting and paginating lists |
|
195 |
SL::Controller::Helper::GetModels - Base class for a the GetModels system. |
|
193 | 196 |
|
194 | 197 |
=head1 SYNOPSIS |
195 | 198 |
|
196 |
For a proper synopsis see L<SL::Controller::Helper::Sorted>.
|
|
199 |
In controller:
|
|
197 | 200 |
|
198 |
=head1 OVERVIEW |
|
201 |
use SL::Controller::Helper::GetModels; |
|
202 |
|
|
203 |
my $get_models = SL::Controller::Helper::GetModels->new( |
|
204 |
controller => $self, |
|
205 |
); |
|
199 | 206 |
|
200 |
For a generic overview see L<SL::Controller::Helper::Sorted>. |
|
207 |
my $models = $self->get_models->get; |
|
208 |
|
|
209 |
=head1 OVERVIEW |
|
201 | 210 |
|
202 |
This base module is the interface between a controller and specialized |
|
203 |
helper modules that handle things like sorting and paginating. The |
|
204 |
specialized helpers register themselves with this module via a call to |
|
205 |
L<register_get_models_handlers> during compilation time (e.g. in the |
|
206 |
case of C<Sorted> this happens when the controller calls |
|
207 |
L<SL::Controller::Helper::Sorted::make_sorted>). |
|
211 |
Building a CRUD controller would be easy, were it not for those stupid |
|
212 |
list actions. People unreasonable expect stuff like filtering, sorting, |
|
213 |
paginating, exporting etc simply to work. Well, lets try to make it simply work |
|
214 |
a little. |
|
208 | 215 |
|
209 |
A controller will later usually call the L<get_models> |
|
210 |
function. Templates will call the L<get_callback> function. Both |
|
211 |
functions run the registered handlers handing over control to the |
|
212 |
specialized helpers so that they may inject their parameters into the |
|
213 |
call chain. |
|
216 |
This class is a proxy between a controller and specialized |
|
217 |
helper modules that handle these things (sorting, paginating etc) and gives you |
|
218 |
the means to retrieve the information when needed to display sort headers or |
|
219 |
paginating footers. |
|
214 | 220 |
|
215 |
The C<GetModels> helper hooks into the controller call to the action |
|
216 |
via a C<run_before> hook. This is done so that it can remember the |
|
217 |
action called by the user. This is used for constructing the callback |
|
218 |
in L<get_callback>. |
|
221 |
Information about the requested data query can be stored into the object up to |
|
222 |
a certain point, from which on the object becomes locked and can only be |
|
223 |
accessed for information. (Seee TODO STAGES). |
|
219 | 224 |
|
220 |
=head1 PACKAGE FUNCTIONS
|
|
225 |
=head1 INTERFACE METHODS
|
|
221 | 226 |
|
222 | 227 |
=over 4 |
223 | 228 |
|
224 |
=item C<get_models_url_params $class, $sub>
|
|
229 |
=item new PARMAS
|
|
225 | 230 |
|
226 |
Register one of the controller's subs to be called whenever an URL has |
|
227 |
to be generated (e.g. for sort and pagination links). This is a way |
|
228 |
for the controller to add additional parameters to the URL (e.g. for |
|
229 |
filter parameters). |
|
231 |
Create a new GetModels object. Params must have at least an entry |
|
232 |
C<controller>, other than that, see C<CONFIGURATION> for options. |
|
230 | 233 |
|
231 |
The C<$sub> parameter can be either a code reference or the name of |
|
234 |
=item get |
|
235 |
|
|
236 |
Retrieve all models for the current configuration. Will finalize the object. |
|
237 |
|
|
238 |
=item get_models_url_params SUB |
|
239 |
|
|
240 |
Register a sub to be called whenever an URL has to be generated (e.g. for sort |
|
241 |
and pagination links). This is a way for the controller to add additional |
|
242 |
parameters to the URL (e.g. for filter parameters). |
|
243 |
|
|
244 |
The parameter can be either a code reference or the name of |
|
232 | 245 |
one of the controller's functions. |
233 | 246 |
|
234 |
The value returned by this C<$sub> must be either a single hash
|
|
247 |
The value returned by C<SUB> must be either a single hash
|
|
235 | 248 |
reference or a hash of key/value pairs to add to the URL. |
236 | 249 |
|
237 |
=item C<register_get_models_handlers $class, %handlers> |
|
250 |
=item get_callback |
|
251 |
|
|
252 |
Returns a URL suitable for use as a callback parameter. It maps to the |
|
253 |
current controller and action. All registered handlers of type |
|
254 |
'callback' (e.g. the ones by C<Sorted> and C<Paginated>) can inject |
|
255 |
the parameters they need so that the same list view as is currently |
|
256 |
visible can be re-rendered. |
|
257 |
|
|
258 |
Optional C<%params> passed to this function may override any parameter |
|
259 |
set by the registered handlers. |
|
260 |
|
|
261 |
=item enable_plugin PLUGIN |
|
262 |
|
|
263 |
=item disable_plugin PLUGIN |
|
264 |
|
|
265 |
=item is_enabled_plugin PLUGIN |
|
238 | 266 |
|
239 |
This function should only be called from other controller helpers like |
|
240 |
C<Sorted> or C<Paginated>. It is not exported and must therefore be |
|
241 |
called its full name. The first parameter C<$class> must be the actual |
|
242 |
controller's class name. |
|
267 |
Enable or disable the specified plugin. Useful to disable paginating for |
|
268 |
exports for example. C<is_enabled_plugin> can be used to check the current |
|
269 |
state fo a plugin. |
|
243 | 270 |
|
244 |
If C<%handlers> contains a key C<ONLY> then it is passed to the hook |
|
245 |
registration in L<SL::Controller::Base::run_before>. |
|
271 |
Must not be finalized to use this. |
|
246 | 272 |
|
247 |
The C<%handlers> register callback functions in the specialized |
|
248 |
controller helpers that are called during invocation of |
|
249 |
L<get_callback> or L<get_models>. Possible keys are C<callback> and |
|
250 |
C<models>. |
|
273 |
=item finalize |
|
251 | 274 |
|
252 |
Each handler (the value in the hash) can be either a code reference |
|
253 |
(in which case it is called directly) or the name of an instance |
|
254 |
function callable on a controller instance. In both cases the handler |
|
255 |
receives a hash of parameters built during this very call to |
|
256 |
L<get_callback> or L<get_models> respectively. The handler's return |
|
257 |
value must be the new hash to be used in calls to further handlers and |
|
258 |
to the actual database model functions later on. |
|
275 |
Forces finalized state. Can be used on finalized objects without error. |
|
276 |
|
|
277 |
Note that most higher functions will call this themselves to force a finalized |
|
278 |
state. If you do use it it must come before any other finalizing methods, and |
|
279 |
will most likely function as a reminder or maintainers where your codes |
|
280 |
switches from configuration to finalized state. |
|
281 |
|
|
282 |
=item source HASHREF |
|
283 |
|
|
284 |
The source for user supplied information. Defaults to $::form. Changing it |
|
285 |
after C<Base> phase has no effect. |
|
286 |
|
|
287 |
=item controller CONTROLLER |
|
288 |
|
|
289 |
A weakened link to the controller that created the GetModels object. Needed for |
|
290 |
certain plugin methods. |
|
259 | 291 |
|
260 | 292 |
=back |
261 | 293 |
|
262 |
=head1 INSTANCE FUNCTIONS |
|
294 |
=head1 DELEGATION METHODS |
|
295 |
|
|
296 |
Methods delegating to C<Sorted>: |
|
263 | 297 |
|
264 | 298 |
=over 4 |
265 | 299 |
|
266 |
=item C<get_callback [%params]>
|
|
300 |
=item *
|
|
267 | 301 |
|
268 |
Return an URL suitable for use as a callback parameter. It maps to the |
|
269 |
current controller and action. All registered handlers of type |
|
270 |
'callback' (e.g. the ones by C<Sorted> and C<Paginated>) can inject |
|
271 |
the parameters they need so that the same list view as is currently |
|
272 |
visible can be re-rendered. |
|
302 |
set_report_generator_sort_options |
|
273 | 303 |
|
274 |
Optional C<%params> passed to this function may override any parameter |
|
275 |
set by the registered handlers. |
|
304 |
=item * |
|
276 | 305 |
|
277 |
=item C<get_models [%params]>
|
|
306 |
get_sort_spec
|
|
278 | 307 |
|
279 |
Query the model manager via C<get_all> and return its result. The |
|
280 |
parameters to C<get_all> are constructed by calling all registered |
|
281 |
handlers of type 'models' (e.g. the ones by C<Sorted> and |
|
282 |
C<Paginated>). |
|
308 |
=item * |
|
283 | 309 |
|
284 |
Optional C<%params> passed to this function may override any parameter |
|
285 |
set by the registered handlers. |
|
310 |
get_current_sort_params |
|
311 |
|
|
312 |
=back |
|
313 |
|
|
314 |
Methods delegating to C<Paginated>: |
|
315 |
|
|
316 |
=over 4 |
|
317 |
|
|
318 |
=item * |
|
286 | 319 |
|
287 |
The return value is the an array reference of C<Rose> models.
|
|
320 |
get_paginate_args
|
|
288 | 321 |
|
289 | 322 |
=back |
290 | 323 |
|
291 |
=head1 BUGS
|
|
324 |
=head1 STATES
|
|
292 | 325 |
|
293 |
Nothing here yet. |
|
326 |
A GetModels object is in one of 3 states at any given time. Their purpose is to |
|
327 |
make a class of bugs impossible that orginated from changing the configuration |
|
328 |
of a GetModels object halfway during the request. This was a huge problem in |
|
329 |
the old implementation. |
|
294 | 330 |
|
295 |
=head1 AUTHOR |
|
331 |
=over 4 |
|
332 |
|
|
333 |
=item Base |
|
334 |
|
|
335 |
This is the state after creating a new object. |
|
336 |
|
|
337 |
=item Init |
|
338 |
|
|
339 |
In this state every information needed from the source ($::form) has beed read |
|
340 |
and subsequent changes to the source have no effect. In the current |
|
341 |
implementation this will called immediately during creation, so that the return |
|
342 |
value of C<new> is already in state C<Init>. |
|
343 |
|
|
344 |
=item Finalized |
|
345 |
|
|
346 |
In this state no new configuration will be accepted so that information gotten |
|
347 |
through the various methods is consistent. Every information retrieval method |
|
348 |
will trigger finalizing. |
|
349 |
|
|
350 |
=back |
|
351 |
|
|
352 |
|
|
353 |
=head1 CONFIGURATION |
|
354 |
|
|
355 |
Most of the configuration will be handed to GetModels on creation via C<new>. |
|
356 |
This is a list of accepted params. |
|
357 |
|
|
358 |
=over 4 |
|
359 |
|
|
360 |
=item controller SELF |
|
361 |
|
|
362 |
The creating controller. Currently this is mandatory. |
|
363 |
|
|
364 |
=item model MODEL |
|
365 |
|
|
366 |
The name of the model for this GetModels instance. If none is given, the model |
|
367 |
is inferred from the name of the controller class. |
|
368 |
|
|
369 |
=item sorted PARAMS |
|
370 |
|
|
371 |
=item paginated PARAMS |
|
372 |
|
|
373 |
=item filtered PARAMS |
|
374 |
|
|
375 |
Configuration for plugins. If the option for any plugin is omitted, it defaults |
|
376 |
to enabled and configured by default. Giving a falsish value as first argument |
|
377 |
will disable the plugin. |
|
378 |
|
|
379 |
If the value is a hashref, it will be passed to the plugin C<init> method. |
|
380 |
|
|
381 |
=item query |
|
382 |
|
|
383 |
=item with_objects |
|
384 |
|
|
385 |
Additional static parts for Rose to include into the final query. |
|
386 |
|
|
387 |
=item source |
|
388 |
|
|
389 |
Source for plugins to pull their data from. Defaults to $::form. |
|
390 |
|
|
391 |
=back |
|
392 |
|
|
393 |
=head1 BUGS AND CAVEATS |
|
394 |
|
|
395 |
=over 4 |
|
396 |
|
|
397 |
=item * |
|
398 |
|
|
399 |
Delegation is not as clean as it should be. Most of the methods rely on action |
|
400 |
at a distance and should be moved out. |
|
401 |
|
|
402 |
=back |
|
403 |
|
|
404 |
=head1 AUTHORS |
|
296 | 405 |
|
297 | 406 |
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt> |
298 | 407 |
|
408 |
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt> |
|
409 |
|
|
299 | 410 |
=cut |
Auch abrufbar als: Unified diff
model Autoerkennung und Doku