Hello fellows, please bear with me, as this is my first contribution to Catalyst.

From the pod: This Plugin validates request parameters against a specification in a file that directly relates to the requests path (like the .fb files when using Formbuilder).

I'm curiuos of your opinions.

Thank you,
Holli

_______________________________________________________


package Catalyst::Plugin::AutoValidate;

use warnings;
use strict;

use YAML qw( LoadFile );

use Catalyst::Request;
use Config::Validate;
use Data::Dumper;
use NEXT;

our $VERSION = 0.01;

sub prepare {
   my $class = shift;
   my $c     = $class->NEXT::prepare( @_ );
my ( $config, $rpath, $spec_root, $spec_file, $validation_spec, $validator ); # config for this package
   $config    = $c->config->{'Catalyst::Plugin::AutoValidate'};
   # the request path
   $rpath     = $c->request->path || $config->{index_spec} || 'index';
   # root dir to look for specifications
   $spec_root = $config->{spec_root} || "$c->{home}/cvspec";
   # spec file, deduced from path
   $spec_file = "$spec_root/${rpath}.".($config->{spec_extension}||"cvs");
# check if there are custom types configured
   if ( $config->{types} )
   {
       # add to the validation module
       if ( ref( $config->{types} ) eq "ARRAY" )
       {
           for ( @{$config->{types}} )
           {
               Config::Validate::add_default_type(%$_);
           }
       }
       else
       {
           Config::Validate->add_default_type(%{$config->{types}});
       }
# move the types, so they won't get reprocessed another time
       $config->{xtypes} = delete $config->{types};
   }
# there is no matching spec file
   unless ( -e $spec_file )
   {
       # that's ok or not, depending if we are paranoid
       $c->request->{validated} = $config->{paranoid} ? 0 : 1;
   }
   else
   {
       # load spec and validate the request against it
       $validation_spec = LoadFile( $spec_file );
$validator = Config::Validate->new( schema => $validation_spec ); # will die if validation fails eval { $validator->validate( config => $c->request->{parameters} ) };

       unless ( $@ )
       {
           $c->request->{validated} = 1;
       }
       else
       {
           $_ = "$@"; s/^.+?validate\(\): //; s/instead.+//;
           $c->request->{validation_error} = "$_";
           $c->request->{validated} = 0;
       }
   }
return $c;
}
1;

__DATA__
=head1 NAME

Catalyst::Plugin::AutoValidate - Catalyst-Plugin for easy automatic validation of Request-Parameters

=head1 VERSION

Version 0.01

=head1 SYNOPSIS

This Plugin validates request parameters against a specification in a file that directly
relates to the requests path (like the .fb files when using Formbuilder).

For the "heavy lifting" it uses L<http://search.cpan.org/~cmo/Config-Validate-0.2.6/lib/Config/Validate.pm>; All validation options from that module are supported, as they get simply passed through.

# application code
package MyApp;
use strict;
use warnings;

use Catalyst qw(AutoValidate);

# MyApp::Controller::Root.pm
# check parameters and display error message when
# appropriate. Does NOT RUN THE CONTROLLER in that case,
# otherwise proceed with controller
sub begin : Private
{
    my ($self, $c) = @_;

    $c->response->body( $c->request->{validation_error} ),
    $c->detach
        unless $c->request->{validated};
}

# $c->{home}/cvspec/math/multiply.cvs (YAML)
a:
    type: integer
b:
    type: integer

# MyApp::Controller::Math.pm
sub multiply : Local
{
    my ($self, $c) = @_;
    # this is safe because Autovalidate ensures both are integers
    $s->stash->{result} = $c->req->param('a') / $c->req->param('a')
}


=head1 CONFIGURATION

__PACKAGE__->config(
'Catalyst::Plugin::AutoValidate' =>
{
    # root dir for looking up specifications
    spec_root => '',
# when set, all requests without specification die
    paranoid  => 0,
# the name of the index spec (for empty paths)
    index_spec => 'index',

    # extension for spec-files
    spec_extension => 'cvs',
# custom types
    types =>
    [
# generator sub that generates a closure, could come in handy for lookups
        {
            name => 'custom',
            validate => sub {
                my $lookup = { exists => 1 };
return sub { die "Not in lookup table!" unless $lookup->{$_[1]} };
            }->()
        },
        # or easier
        sub { die "Doesnt match!" unless $_[1] =~ /[abc]/ };
    ]
}
);

=cut


=head1 AUTHOR

Markus Holzer, C<< <holli.holzer at googlemmail.com> >>

=head1 BUGS

Please report any bugs or feature requests to C<bug-catalyst-plugin-AutoValidate at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Catalyst-Plugin-AutoValidate>. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.




=head1 SUPPORT

You can find documentation for this module with the perldoc command.

   perldoc Catalyst::Plugin::AutoValidate


You can also look for information at:

=over 4

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Catalyst-Plugin-AutoValidate>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/Catalyst-Plugin-AutoValidate>

=item * CPAN Ratings

L<http://cpanratings.perl.org/d/Catalyst-Plugin-AutoValidate>

=item * Search CPAN

L<http://search.cpan.org/dist/Catalyst-Plugin-AutoValidate>

=back


=head1 ACKNOWLEDGEMENTS


=head1 COPYRIGHT & LICENSE

Copyright 2008 Markus Holzer, all rights reserved.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.


=cut


_______________________________________________
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/

Reply via email to