File Coverage

blib/lib/Class/CGI.pm
Criterion Covered Total %
statement 165 165 100.0
branch 55 56 98.2
condition 13 18 72.2
subroutine 27 27 100.0
pod 14 14 100.0
total 274 280 97.8


line stmt bran cond sub pod time code
1             package Class::CGI;
2              
3 8     8   271158 use warnings;
  8         18  
  8         309  
4 8     8   39 use strict;
  8         16  
  8         251  
5              
6 8     8   10956 use CGI::Simple 0.077;
  8         148581  
  8         63  
7 8     8   8441 use File::Spec::Functions 'catfile';
  8         7213  
  8         655  
8 8     8   10193 use HTML::Entities ();
  8         92528  
  8         479  
9 8     8   97 use base 'CGI::Simple';
  8         16  
  8         1714  
10              
11             =head1 NAME
12              
13             Class::CGI - Fetch objects from your CGI object
14              
15             =head1 VERSION
16              
17             Version 0.20
18              
19             =cut
20              
21             our $VERSION = '0.20';
22              
23             =head1 SYNOPSIS
24              
25             use Class::CGI
26             handlers => {
27             customer_id => 'My::Customer::Handler'
28             };
29              
30             my $cgi = Class::CGI->new;
31             my $customer = $cgi->param('customer_id');
32             my $name = $customer->name;
33             my $email = $cgi->param('email'); # behaves like normal
34              
35             if ( my %errors = $cgi->errors ) {
36             # do error handling
37             }
38              
39             =head1 DESCRIPTION
40              
41             For small CGI scripts, it's common to get a parameter, untaint it, pass it to
42             an object constructor and get the object back. This module would allow one to
43             to build C handler classes which take the parameter value,
44             automatically perform those steps and just return the object. Much grunt work
45             goes away and you can get back to merely I to work.
46              
47             =head1 ALPHA CODE
48              
49             Note that this work is still under development. It is not yet suitable for
50             production work as the interface may change. Join the mailing list in the
51             L section if you would like to influence the future direction of this
52             project.
53              
54             =head1 EXPORT
55              
56             None.
57              
58             =head1 BASIC USE
59              
60             The simplest method of using C is to simply specify each form
61             parameter's handler class in the import list:
62              
63             use Class::CGI
64             handlers => {
65             customer => 'My::Customer::Handler',
66             sales => 'Sales::Loader'
67             };
68              
69             my $cgi = Class::CGI->new;
70             my $customer = $cgi->param('customer');
71             my $email = $cgi->param('email');
72             # validate email
73             $customer->email($email);
74             $customer->save;
75              
76             Note that there is no naming requirement for the handler classes and any form
77             parameter which does not have a handler class behaves just like a normal form
78             parameter. Each handler class is expected to have a constructor named C
79             which takes the B form value and returns an object corresponding to that
80             value. All untainting and validation is expected to be dealt with by the
81             handler. See L.
82              
83             If you need different handlers for the same form parameter names (this is
84             common in persistent environments) you may omit the import list and use the
85             C method.
86              
87             =head1 LOADING THE HANDLERS
88              
89             When the handlers are specified, either via the import list or the
90             C method, we verify that the handler exists and C if it
91             is not. However, we do not load the handler until the parameter for that
92             handler is fetched. This allows us to not load unused handlers but still have
93             a semblance of safety that the handlers actually exist.
94              
95             =head1 METHODS
96              
97             =cut
98              
99             my %class_for;
100              
101             sub import {
102 13     13   2124 my $class = shift;
103              
104 13         27 my ( $config, $use_profiles );
105 13         41 @_ = @_; # this avoids the "modification of read-only value" error when
106             # we assign undef the elements
107 13         47 foreach my $i ( 0 .. $#_ ) {
108              
109             # we sometimes hit unitialized values due to "undef"ing array elements
110 8     8   48 no warnings 'uninitialized';
  8         16  
  8         11899  
111 25         58 my ( $arg, $value ) = @_[ $i, $i + 1 ];
112 25 100       72 if ( 'handlers' eq $arg ) {
113 6 100 100     46 if ( !ref $value || 'HASH' ne ref $value ) {
114 2         5 $class->_croak("No handlers defined");
115             }
116 4         21 while ( my ( $profile, $handler ) = each %$value ) {
117 8         33 $class_for{$profile} = $handler;
118             }
119 4         10 @_[ $i, $i + 1 ] = ( undef, undef );
120 4         9 next;
121             }
122 19 100       55 if ( 'use' eq $arg ) {
123 3 100       13 $value = [$value] unless 'ARRAY' eq ref $value;
124 3         8 $use_profiles = $value;
125 3         9 @_[ $i, $i + 1 ] = ( undef, undef );
126 3         7 next;
127             }
128 16 100       50 if ( 'profiles' eq $arg ) {
129 5 100       105 if ( -f $value ) {
130 4         1196 require Config::Std;
131 4         25916 Config::Std->import;
132 4         184 read_config( $value => \$config );
133             }
134             else {
135              
136             # eventually we may want to allow them to specify a config
137             # class instead of a file.
138 1         9 $class->_croak("Can't find profile file '$value'");
139             }
140 4         8045 @_[ $i, $i + 1 ] = ( undef, undef );
141             }
142             }
143 10 100       47 if ($config) {
144 4 100       11 unless ($use_profiles) {
145 1         3 while ( my ( $profile, $handler )
  6         15  
146             = each %{ $config->{profiles} } )
147             {
148              
149             # the "unless" is here because users may override profile
150             # parameter specifications in their code, if they prefer
151 5 100       14 $class_for{$profile} = $handler
152             unless exists $class_for{$profile};
153             }
154             }
155             else {
156 3         9 foreach my $profile (@$use_profiles) {
157 5 100       24 my $handler = $config->{profiles}{$profile}
158             or
159             $class->_croak("No handler found for parameter '$profile'");
160 4         11 $class_for{$profile} = $handler;
161             }
162             }
163             }
164              
165 9         545 @_ = grep {defined} @_;
  18         37  
166 9         47 $class->_verify_installed( values %class_for );
167 9         75 goto &CGI::Simple::import; # don't update the call stack
168             }
169              
170             # testing hook
171             sub _clear_global_handlers {
172 1     1   370 %class_for = ();
173             }
174              
175             sub _verify_installed {
176 16     16   40 my ( $proto, @modules ) = @_;
177 16         21 my @not_installed_modules;
178 16         34 foreach my $module (@modules) {
179 31 100       69 _module_exists($module)
180             or push @not_installed_modules => $module;
181             }
182 16 100       66 if (@not_installed_modules) {
183 1         8 $proto->_croak(
184             "The following modules are not installed: (@not_installed_modules)"
185             );
186             }
187 15         33 return $proto;
188             }
189              
190             ##############################################################################
191              
192             =head2 new
193              
194             my $cgi = Class::CGI->new(@args);
195              
196             This method takes the same arguments (if any) as L's constructor.
197              
198             =cut
199              
200             sub new {
201 15     15 1 4573 my $class = shift;
202 15         121 my $self = $class->SUPER::new(@_);
203 15         2658 $self->{class_cgi_handlers} = {};
204 15         46 $self->{class_cgi_args} = {};
205 15         50 $self->{class_cgi_errors} = {};
206 15         56 $self->{class_cgi_missing} = {};
207 15         37 $self->{class_cgi_required} = {};
208 15         30 $self->{class_cgi_error_encoding} = undef;
209 15         55 return $self;
210             }
211              
212             ##############################################################################
213              
214             =head2 handlers
215              
216             use Class::CGI;
217             my $cust_cgi = Class::CGI->new;
218             $cust_cgi->handlers(
219             customer => 'My::Customer::Handler',
220             );
221             my $order_cgi = Class::CGI->new($other_params);
222             $order_cgi->handlers(
223             order => 'My::Order::Handler',
224             );
225             my $customer = $cust_cgi->param('customer');
226             my $order = $order_cgi->param('order');
227             $order->customer($customer);
228              
229             my $handlers = $cgi->handlers; # returns hashref of current handlers
230            
231             Sometimes we get our CGI parameters from different sources. This commonly
232             happens in a persistent environment where the class handlers for one form may
233             not be appropriate for another form. When this occurs, you may set the
234             handler classes on an instance of the C object. This overrides
235             global class handlers set in the import list:
236              
237             use Class::CGI handlers => {
238             customer => "Some::Customer::Handler",
239             order => "My::Order::Handler"
240             };
241             my $cgi = Class::CGI->new;
242             $cgi->handlers( customer => "Some::Other::Customer::Handler" );
243              
244             In the above example, the C<$cgi> object will not use the
245             C class. Further, the "order" handler will B be
246             available. Setting hanlders on an makes the global handlers unavailable. If
247             you also needed the "order" handler, you need to specify that in the
248             C<&handlers> method.
249              
250             If called without arguments, returns a hashref of the current handlers in
251             effect.
252              
253             =cut
254              
255             sub handlers {
256 11     11 1 2493 my $self = shift;
257 11 100       55 if ( my %handlers = @_ ) {
258 7         24 $self->{class_cgi_handlers} = \%handlers;
259 7         37 $self->_verify_installed( values %handlers );
260 6         31 return $self;
261             }
262              
263             # else called without arguments
264 4 100       6 if ( my %handlers = %{ $self->{class_cgi_handlers} } ) {
  4         25  
265 2         14 return \%handlers;
266             }
267 2         12 return \%class_for;
268             }
269              
270             ##############################################################################
271              
272             =head2 profiles
273              
274             $cgi->profiles($profile_file, @use);
275              
276             If you prefer, you can specify a config file listing the available
277             C profile handlers and an optional list stating which of the
278             profiles to use. If the C<@use> list is not specified, all profiles will be
279             used. Otherwise, only those profiles listed in C<@use> will be used. These
280             profiles are used on a per instance basis, similar to C<&handlers>.
281              
282             See L for more information about the profile configuration
283             file.
284              
285             =cut
286              
287             sub profiles {
288 4     4 1 2472 my ( $self, $profiles, @use ) = @_;
289 4 100       80 unless ( -f $profiles ) {
290              
291             # eventually we may want to allow them to specify a config
292             # class instead of a file.
293 1         7 $self->_croak("Can't find profile file '$profiles'");
294             }
295              
296 3         19 require Config::Std;
297 3         22 Config::Std->import;
298 3         160 read_config( $profiles => \my %config );
299 3         4995 my %handler_for = %{ $config{profiles} };
  3         19  
300 3 100       400 if (@use) {
301 2         4 my %used;
302 2         7 foreach my $profile (@use) {
303 2 100       9 if ( exists $handler_for{$profile} ) {
304 1         5 $used{$profile} = 1;
305             }
306             else {
307 1         7 $self->_croak("No handler found for parameter '$profile'");
308             }
309             }
310 1         5 foreach my $profile ( keys %handler_for ) {
311 5 100       23 delete $handler_for{$profile} unless $used{$profile};
312             }
313             }
314 2         20 $self->handlers(%handler_for);
315             }
316              
317             ##############################################################################
318              
319             =head2 param
320              
321             use Class::CGI
322             handlers => {
323             customer => 'My::Customer::Handler'
324             };
325              
326             my $cgi = Class::CGI->new;
327             my $customer = $cgi->param('customer'); # returns an object, if found
328             my $email = $cgi->param('email'); # returns the raw value
329             my @sports = $cgi->param('sports'); # behaves like you would expect
330              
331             If a handler is defined for a particular parameter, the C calls the
332             C method for that handler, passing the C object and the
333             parameter's name. Returns the value returned by C. In the example
334             above, for "customer", the return value is essentially:
335              
336             return My::Customer::Handler->new( $self, 'customer' );
337              
338             =cut
339              
340             sub param {
341 67     67 1 17286 my $instance_handlers = $_[0]->{class_cgi_handlers};
342 67 100       171 my $handler_for = %$instance_handlers ? $instance_handlers : \%class_for;
343 67 100 66     508 if ( 2 != @_ || ( 2 == @_ && !exists $handler_for->{ $_[1] } ) ) {
      66        
344              
345             # this allows multi-valued params for parameters which do not have
346             # helper classes and also allows for my @params = $cgi->param;
347 46         173 goto &CGI::Simple::param;
348             }
349 21         45 my ( $self, $param ) = @_;
350 21         44 my $class = $handler_for->{$param};
351 21         1335 eval "require $class";
352 21 100       4616 $self->_croak("Could not load '$class': $@") if $@;
353 19         30 my $result;
354 19         29 eval { $result = $class->new( $self, $param ) };
  19         93  
355 19 100       569 if ( my $error = $@ ) {
356 5         15 $self->add_error( $param, $error );
357 5         19 return;
358             }
359 14         104 return $result;
360             }
361              
362             ##############################################################################
363              
364             =head2 raw_param
365              
366             my $id = $cgi->raw_param('customer');
367              
368             This method returns the actual value of a parameter, ignoring any handlers
369             defined for it.
370              
371             =cut
372              
373             sub raw_param {
374 20     20 1 881 my $self = shift;
375 20         107 return $self->SUPER::param(@_);
376             }
377              
378             ##############################################################################
379              
380             =head2 args
381              
382             $cgi->args('customer', \@whatever_you_want);
383              
384             my $args = $cgi->args($param);
385              
386             This method allows you to pass extra arguments to a handler. Specify the name
387             of the parameter for which you wish to provide the arguments and then provide
388             a I argument (it may be a reference). In your handler, you can access
389             it like this:
390              
391             package Some::Handler;
392              
393             sub new {
394             my ( $class, $cgi, $param ) = @_;
395              
396             my $args = $cgi->args($param);
397             ...
398             }
399              
400             =cut
401              
402             sub args {
403 2     2 1 928 my $self = shift;
404 2         3 my $param = shift;
405 2         5 my $arg_for = $self->{class_cgi_args};
406             {
407 8     8   52 no warnings 'uninitialized';
  8         13  
  8         5817  
  2         3  
408 2 100       8 return $arg_for->{$param} unless @_;
409             }
410              
411 1         4 $arg_for->{$param} = shift;
412 1         3 return $self;
413             }
414              
415             ##############################################################################
416              
417             =head2 errors
418              
419             if ( my %errors = $cgi->errors ) {
420             ...
421             }
422              
423             Returns exceptions thrown by handlers, if any. In scalar context, returns a
424             hash reference. Note that these exceptions are generated via the overloaded
425             C<¶m> method. For example, let's consider the following:
426              
427             use Class::CGI
428             handlers => {
429             customer => 'My::Customer::Handler',
430             date => 'My::Date::Handler',
431             order => 'My::Order::Handler',
432             };
433              
434             my $cgi = Class::CGI->new;
435             my $customer = $cgi->param('customer');
436             my $date = $cgi->param('date');
437             my $order = $cgi->param('order');
438              
439             if ( my %errors = $cgi->errors ) {
440             # do error handling
441             }
442              
443             If errors are generated by the param statements, returns a hash of the errors.
444             The keys are the param names and the values are whatever exception the handler
445             throws. Returns a hashref in scalar context.
446              
447             If no errors were generated, this method simply returns. This allows you to
448             do this:
449              
450             if ( $cgi->errors ) { ... }
451              
452             If any of the C<< $cgi->param >> calls generates an error, it will B throw
453             an exception. Instead, control will pass to the next statement. After all
454             C<< $cgi->param >> calls are made, you can check the C<&errors> method to see
455             if any errors were generated and, if so, handle them appropriately.
456              
457             This allows the programmer to validate the entire set of form data and report
458             all errors at once. Otherwise, you wind up with the problem often seen on Web
459             forms where a customer will incorrectly fill out multiple fields and have the
460             Web page returned for the first error, which gets corrected, and then the page
461             returns the next error, and so on. This is very frustrating for a customer
462             and should be avoided at all costs.
463              
464             =cut
465              
466             sub errors {
467 12     12 1 26 my $self = shift;
468 12         25 my $errors = $self->{class_cgi_errors};
469 12 100       38 return unless %$errors;
470 9 100       61 return wantarray ? %$errors : $errors;
471             }
472              
473             ##############################################################################
474              
475             =head2 clear_errors
476              
477             $cgi->clear_errors;
478              
479             Deletes all errors returned by the C<&errors> method.
480              
481             =cut
482              
483             sub clear_errors {
484 1     1 1 3 my $self = shift;
485 1         3 $self->{class_cgi_errors} = {};
486 1         4 return $self;
487             }
488              
489             ##############################################################################
490              
491             =head2 add_error
492              
493             $cgi->add_error( $param, $error );
494              
495             This method add an error for the given parameter.
496              
497             =cut
498              
499             sub add_error {
500 9     9 1 20 my ( $self, $param, $error ) = @_;
501 9         26 $error = HTML::Entities::encode_entities( $error, $self->error_encoding );
502 9         1025 $self->{class_cgi_errors}{$param} = $error;
503 9         23 return $self;
504             }
505              
506             ##############################################################################
507              
508             =head2 add_missing
509              
510             $cgi->add_missing( $param, $optional_error_message );
511              
512             Helper function used in handlers to note that a parameter is "missing". This
513             should only be used for "required" parameters. Calling this method with a
514             non-required parameter is a no-op. See the L and C
515             methods.
516              
517             Missing parameters will be reported via the L and
518             L methods.
519              
520             =cut
521              
522             sub add_missing {
523 2     2 1 6 my ( $self, $param, $message ) = @_;
524 2 50       9 return unless $self->is_required($param);
525 2         8 $self->{class_cgi_missing}{$param} = 1;
526 2   66     18 $self->add_error(
527             $param,
528             $message || "You must supply a value for $param"
529             );
530 2         10 return $self;
531             }
532              
533             ##############################################################################
534              
535             =head2 is_missing_required
536              
537             if ( $cgi->is_missing_required( $param ) ) {
538             ...
539             }
540              
541             Returns a boolean value indicating whether or not a required parameter is
542             missing. Always return false for parameters which are not required.
543              
544             Note that this value is set via the L method.
545              
546             =cut
547              
548             sub is_missing_required {
549 4     4 1 11 my ( $self, $param ) = @_;
550 4   66     35 return $self->{class_cgi_missing}{$param} || ();
551             }
552              
553             ##############################################################################
554              
555             =head2 error_encoding
556              
557             $cgi->error_encoding( $unsafe_characters );
558              
559             Error messages must be properly escaped for display in HTML. We use
560             C to handle the encoding. By default, this encodes control
561             characters, high bit characters, and the "<", "&", ">", "'" and """
562             characters. This should suffice for most uses.
563              
564             If you need to specify a different set of characters to encode, you may set
565             them with this method. See the C documentation in
566             L for details on the C<$unsafe_characters>.
567              
568             =cut
569              
570             sub error_encoding {
571 10     10 1 959 my $self = shift;
572 10 100 66     97 return $self->{class_cgi_error_encoding} || () unless @_;
573 1         3 $self->{class_cgi_error_encoding} = shift;
574 1         4 return $self;
575             }
576              
577             ##############################################################################
578              
579             =head2 required
580              
581             $cgi->required(@required_parameters);
582              
583             Allows you to set which parameters are required for this C object.
584             Any previous "required" parameters will be cleared.
585              
586             =cut
587              
588             sub required {
589 2     2 1 691 my $self = shift;
590 2         24 $self->{class_cgi_required} = {};
591 2         5 foreach my $param (@_) {
592 5         14 $self->{class_cgi_required}{$param} = 1;
593             }
594 2         7 return 1;
595             }
596              
597             ##############################################################################
598              
599             =head3 is_required
600              
601             if ( $cgi->is_required($param) ) {
602             ...
603             }
604              
605             Generally used in handlers, this method returns a boolean value indicating
606             whether or not a given parameter is required.
607              
608             =cut
609              
610             sub is_required {
611 6     6 1 15 my ( $self, $param ) = @_;
612 6         41 return exists $self->{class_cgi_required}{$param};
613             }
614              
615             sub _croak {
616 9     9   20 my ( $proto, $message ) = @_;
617 9         51 require Carp;
618 9         164 Carp::croak $message;
619             }
620              
621             sub _module_exists {
622 31     31   43 my $module_name = shift;
623 31         248 my @parts = split /(?:::|')/, $module_name;
624 31         136 $parts[-1] .= '.pm';
625              
626 31         93 for (@INC) {
627 40 100       2300 return 1 if -f catfile( $_, @parts );
628             }
629 1         6 return;
630             }
631              
632             =head1 WRITING HANDLERS
633              
634             =head2 A basic handler
635              
636             Handlers are usually pretty easy to write. There are a few simple rules to
637             remember.
638              
639             =over 4
640              
641             =item * Inherit from L.
642              
643             =item * Provide a method named C which takes C<$self> as an argument.
644              
645             =item * Return whatever value you want.
646              
647             =item * For virtual parameters, override the C method.
648              
649             =back
650              
651             And that's pretty much it. See the L documentation for
652             what methods are available to call on C<$self>. The ones which will probably
653             always be used are the C and C methods.
654              
655             Writing a handler is a fairly straightforward affair. Let's assume that our
656             form has a parameter named "customer" and this parameter should point to a
657             customer ID. The ID is assumed to be a positive integer value. For this
658             example, we assume that our customer class is named C and we
659             load a customer object with the C method. The handler might
660             look like this:
661              
662             package My::Customer::Handler;
663            
664             use base 'Class::CGI::Handler';
665            
666             use My::Customer;
667            
668             sub handle {
669             my $self = shift;
670             my $cgi = $self->cgi;
671             my $param = $self->param;
672            
673             my $id = $cgi->raw_param($param);
674            
675             unless ( $id && $id =~ /^\d+$/ ) {
676             die "Invalid id ($id) for $class";
677             }
678             return My::Customer->load_from_id($id)
679             || die "Could not find customer for ($id)";
680             }
681            
682             1;
683              
684             Pretty simple, eh?
685              
686             Using this in your code is as simple as:
687              
688             use Class::CGI
689             handlers => {
690             customer => 'My::Customer::Handler',
691             };
692              
693             If C is being used in a persistent environment and other forms
694             might have a param named C but this param should not become a
695             C object, then set the handler on the instance instead:
696              
697             use Class::CGI;
698             my $cgi = Class::CGI->new;
699             $cgi->handlers( customer => 'My::Customer::Handler' );
700              
701             B: Note that earlier versions of C listed handlers
702             with names like C. It is recommended that you not use the
703             C namespace to avoid possibly conflicts with handlers which may
704             be released to the CPAN in this namespace I you also intend to release
705             your module to the CPAN in this namespace.
706              
707             =head2 A more complex example
708              
709             As a more common example, let's say you have the following data in a form:
710              
711            
712            
713             ...
714            
715            
716            
717            
718             ...
719            
720            
721            
722            
723             ...
724            
725            
726              
727             Ordinarily, pulling all of that out, untainting it is a pain. Here's a
728             hypothetical handler for it:
729              
730             package My::Date::Handler;
731              
732             use base 'Class::CGI::Handler';
733             use My::Date;
734              
735             sub handle {
736             my $self = shift;
737             my $cgi = $self->cgi;
738             my $month = $cgi->raw_param('month');
739             my $day = $cgi->raw_param('day');
740             my $year = $cgi->raw_param('year');
741             return My::Date->new(
742             month => $month,
743             day => $day,
744             year => $year,
745             );
746             }
747              
748             # because this is a virtual parameter, we must override the has_param()
749             # method.
750             sub has_param {
751             my $self = shift;
752             return $self->has_virtual_param( date => qw/day month year/ );
753             }
754              
755             1;
756              
757             And in the user's code:
758              
759             use Class::CGI
760             handlers => {
761             date => 'My::Date::Handler',
762             };
763              
764             my $cgi = Class::CGI->new;
765             my $date = $cgi->param('date');
766             my $day = $date->day;
767              
768             Note that this does not even require an actual param named "date" in the form.
769             The handler encapsulates all of that and the end user does not need to know
770             the difference.
771              
772             =head2 Virtual parameters
773              
774             Note that the parameter a user fetches might not exist on the form. In the
775             C<< $cgi->param('date') >> example above, there is no "date" parameter.
776             Instead, it's a composite formed of other fields. It's strongly recommended
777             that if you have a handler which uses virtual parameters that you B
778             use a parameter with the same name. If you must, you can still access the
779             value of the real parameter with C<< $cgi->raw_param('date'); >>.
780              
781             =head2 Reusing handlers
782              
783             Sometimes you might want to use a handler more than once for the same set of
784             data. For example, you might want to have more than one date on a page. To
785             handle issues like this, we pass in the parameter name to the constructor so
786             you can know I date you're trying to fetch.
787              
788             So for example, let's say their are three dates in a form. One is the
789             customer birth date, one is an order date and one is just a plain date. Maybe
790             our code will look like this:
791              
792             $cgi->handlers(
793             birth_date => 'My::Date::Handler',
794             order_date => 'My::Date::Handler',
795             date => 'My::Date::Handler',
796             );
797              
798             One way of handling that would be the following:
799              
800             package My::Date::Handler;
801            
802             use base 'Class::CGI::Handler';
803             use strict;
804             use warnings;
805            
806             use My::Date;
807            
808             sub handle {
809             my $self = shift;
810             my $cgi = $self->cgi;
811             my $param = $self->param;
812              
813             my $prefix;
814             if ( 'date' eq $param ) {
815             $prefix = '';
816             }
817             else {
818             ($prefix = $param) =~ s/date$//;
819             }
820             my ( $day, $month, $year ) =
821             grep {defined}
822             map { $cgi->raw_param($_) } $self->components;
823              
824             return My::Date->new(
825             day => $day,
826             month => $month,
827             year => $year,
828             );
829             }
830              
831             sub components {
832             my $self = shift;
833             my $cgi = $self->cgi;
834             my $param = $self->param;
835              
836             my $prefix;
837             if ( 'date' eq $param ) {
838             $prefix = '';
839             }
840             else {
841             ($prefix = $param) =~ s/date$//;
842             }
843             return map { "$prefix$_" } qw/day month year/;
844             }
845              
846             sub has_param {
847             my $self = shift;
848             return $self->has_virtual_param( $self->param, $self->components );
849             }
850            
851             1;
852              
853             For that, the birthdate will be built from params named C,
854             C and C. The order date would be C and so
855             on. The "plain" date would be built from params named C, C, and
856             C. Thus, all three could be accessed as follows:
857              
858             my $birthdate = $cgi->param('birth_date');
859             my $order_date = $cgi->param('order_date');
860             my $date = $cgi->param('date');
861              
862             =head1 DEFINING PROFILES
863              
864             Handlers for parameters may be defined in an import list:
865              
866             use Class::CGI
867             handlers => {
868             customer => 'My::Customer::Handler',
869             order_date => 'My::Date::Handler',
870             order => 'My::Order::Handler',
871             };
872              
873             =head2 Creating a profile file
874              
875             For larger sites, it's not very practical to replicate this in all code which
876             needs it. Instead, C allows you to define a "profiles" file.
877             This is a configuration file which should match the C format. At
878             the present time, only one section, "profiles", is supported. This should be
879             followed by a set of colon-delimited key/value pairs specifying the CGI
880             parameter name and the handler class for the parameter. The above import list
881             could be listed like this in the file:
882              
883             [profiles]
884             customer: My::Customer::Handler
885             order_date: My::Date::Handler
886             order: My::Order::Handler
887              
888             You may then use the profiles in your code as follows:
889              
890             use Class::CGI profiles => $location_of_profile_file;
891              
892             It may be the case that you don't want all of the profiles. In that case, you
893             can list a "use" section for that:
894              
895             use Class::CGI
896             profiles => $location_of_profile_file,
897             use => [qw/ order_date order /];
898            
899             As with C<&handlers>, you may find that you don't want the profiles globally
900             applied. In that case, use the C<&profiles> method described above:
901              
902             $cgi->profiles( $profile_file, @optional_list_of_profiles_to_use );
903              
904             =head1 DESIGN CONSIDERATIONS
905              
906             =head2 Subclassing CGI::Simple
907              
908             Because this module is a subclass of C, all of C's
909             methods and behaviors should be available. We do not subclass off of C
910             because C is faster and it's assumed that if we're going the full
911             OO route that we are already using templates. Thus, the C HTML
912             generation methods are not available and should not be needed. This decision
913             may be revisited in the future.
914              
915             More to the point, CGI.pm, while being faster and more lightweight than most
916             people give it credit for, is a pain to subclass. Further, it would need to
917             be subclassed without exposing the functional interface due to the need to
918             maintain state in C.
919              
920             =head2 Delayed loading
921              
922             When handlers are specified, either at compile time or setting them on an
923             instance, the existence of the handlers is verified. However, the handlers
924             are not loaded until used, thus reducing memory usage if they are not needed.
925              
926             In a similar vein, if you choose to use a profile file (see L
927             profile file>), C is used. However, that module is also not
928             loaded unless needed.
929              
930             =head2 Why not Data::FormValidator?
931              
932             The biggest complaint about C seems to be that it's "reinventing
933             the wheel". Before you agree with that complaint, see
934             L. Pointy-haired boss summary of
935             that link: you had better reinvent the wheel if you're creating a motorcycle
936             instead of a car.
937              
938             There's nothing wrong with C. It's fast, powerful, and
939             well-proven in its approach. C, in fact, can easily benefit from
940             C inside of handler classes. However, the approach we
941             take is fundamentally different. First, instead of learning a list of
942             required hash keys and trying to remember what C, C,
943             C, C and so on do, you just need
944             to know that a handler constructor takes a C instance and the
945             parameter name. Everything else is just normal Perl code, no memorization
946             required.
947              
948             With C, you can pick and choose what handlers you wish to support
949             for a given piece of code. You can have a global set of handlers to enforce
950             consistency in your Web site or you can have "per page" handlers set up as
951             needed.
952              
953             =head1 TODO
954              
955             This module should be considered alpha code. It probably has bugs. Comments
956             and suggestions welcome.
957              
958             =head1 AUTHOR
959              
960             Curtis "Ovid" Poe, C<< >>
961              
962             =head1 SUPPORT
963              
964             There is a mailing list at L.
965             Currently it is low volume. That might change in the future.
966              
967             =head1 BUGS
968              
969             Please report any bugs or feature requests to
970             C, or through the web interface at
971             L.
972             I will be notified, and then you'll automatically be notified of progress on
973             your bug as I make changes.
974              
975             If you are unsure if a particular behavior is a bug, feel free to send mail to
976             the mailing list.
977              
978             =head1 SEE ALSO
979              
980             This module is based on the philosophy of building super-simple code which
981             solves common problems with a minimum of memorization. That being said, it
982             may not be the best fit for your code. Here are a few other options to
983             consider.
984              
985             =over 4
986              
987             =item *
988             Data::FormValidator - Validates user input based on input profile
989              
990             =item *
991             HTML::Widget - HTML Widget And Validation Framework
992              
993             =item *
994             Rose::HTML::Objects - Object-oriented interfaces for HTML
995              
996             =back
997              
998             =head1 ACKNOWLEDGEMENTS
999              
1000             Thanks to Aristotle for pointing out how useful passing the parameter name to
1001             the handler would be.
1002              
1003             =head1 COPYRIGHT & LICENSE
1004              
1005             Copyright 2006 Curtis "Ovid" Poe, all rights reserved.
1006              
1007             This program is free software; you can redistribute it and/or modify it
1008             under the same terms as Perl itself.
1009              
1010             =cut
1011              
1012             1;