/opt/foobar/apps/---+ | | | | | Foobar_Super.pm | | | Common.pm | | | /Acmecorp/---+ | | | Contact.pm | | | acmecorp.conf | | /var/www/acmecorp/--+ | home.html | /contact/----+ | | | index.cgi | /templates/---+ | | | contact.tmpl | thankyou.html #### #!/usr/local/bin/perl -T use lib "/opt/foobar/apps/"; use warnings; use strict; use Acmecorp::Contact; my $app = Acmecorp::Contact->new( PARAM => 'client' ); $app->run(); ####

Today's date:

Name:

Address:

City:

More info:

##
## package Foobar_Super; use strict; use warnings; use base 'CGI::Application'; use CGI::Application::Plugin::FillInForm(qw/fill_form/); use CGI::Application::Plugin::Config::Simple; use CGI::Application::Plugin::Redirect; use CGI::Application::Plugin::Session; use CGI::Application::Plugin::DBH (qw/dbh_config dbh/); use HTML::Template; #--- Start CGI::APP sub cgiapp_init { my $self = shift; #--- Set Paths $self->config_file( '/opt/foobar/' . ucfirst $self->param('client') .'/'. $self->param('client').'.conf');; $self->tmpl_path( '/var/www/' . $self->param('client') . '/templates ); #--- Session $self->session_config( DEFAULT_EXPIRY => '+8h'); #--- Contact to DB $self->dbh_config( $self->config_param('db.host'), $self->config_param('db.user'), $self->config_param('db.pass'), {RaiseError => 1} ); } 1; #### #--- MySQL Server --- [db] host = DBI:mysql:foobar:localhost user = acmecorp pass = AKCgKYxc #### package Acmecorp::Contact; use base qw(Foobar_Super Common); use strict; use warnings; use MIME::Lite; #load any extra modules needed use Date::Calc qw(Today); #--- SETUP Runmodes sub setup { my $self = shift; $self->start_mode('d'); #if no runmode, use 'd' $self->mode_param('rm'); $self->run_modes( 'd' => 'display', 's' => 'save_form' ); } #--- Display sub display { my $self = shift; my $template = $self->load_tmpl( 'contact.tmpl', die_on_bad_params => 0 ); $template->param( today => sprintf( '%4d-%02d-%02d', Today() ) ); return $template->output(); } #--- Process sub save_form { my $self = shift; my ( %sql, @errors, $error, $fifvalues ); ($sql{'name'}, $error ) = $self->validate( $self->query->param('name') ); if ( $error ) { push @errors, ( { 'error' => 'Name'.$error } ); } ($sql{'address'}, $error ) = $self->validate( $self->query->param('address') ); if ( $error ) { push @errors, ( { 'error' => 'Address'.$error } ); } ($sql{'city'}, $error ) = $self->validate( $self->query->param('city') ); if ( $error ) { push @errors, ( { 'error' => 'City'.$error } ); } $sql{'more_info'} = $self->query->param('more_info'); #if there are errors, return the form with original input and error messages if ( @errors ) { my $template = $self->load_tmpl( 'contact.tmpl', die_on_bad_params => 0, ); $template->param( errors => \@errors, today => sprintf( '%4d-%02d-%02d', Today() ), ); for my $key ( keys %sql ) { $fifvalues->{$key} = $sql{$key}; #assign fill-in-form values } return $self->fill_form( \$template->output, $fifvalues ); } else { $self->record(\%sql); #record the input return $self->redirect('/thankyou.html'); } } #--- Record sub record { my $self = shift; my $sql = shift; my %sql = %{ $sql }; #we use CAP::DBH to connect to the DB and execute our SQL statement my $stmt = 'INSERT INTO contacts (' . join(',', keys %sql) . ') VALUES (' . join(',', ('?') x keys %sql) . ')'; $self->dbh->do($stmt, undef, values %sql); } 1;

Common.pm (a module with common methods)

package Common; sub validate { my $self = shift; my $to_check = shift; if ( $to_check !~ /^([\w ]+)$/ ) { return ( $to_check, " has invalid characters or is blank" ); } else { return $1; } } 1;