Class:...FromCGI(3pm)

πŸ“¦
version 1.00 Β· 3 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– Class::DBI::FromCGI πŸ’–

okay bestie, so this is a page from the User Contributed Perl Documentation collection, and it's about a lil module called Class::DBI::FromCGI πŸ’… let's get into it.


✨ NAME ✨

Class::DBI::FromCGI β€” update your Class::DBI data using CGI::Untaint. it's giving "these two modules are besties and we're the group chat that introduced them" 🫢


🌸 SYNOPSIS 🌸

package Film;
use Class::DBI::FromCGI;
use base 'Class::DBI';
# set up as any other Class::DBI class.

__PACKAGE__->untaint_columns(
  printable => [qw/Title Director/],
  integer   => [qw/DomesticGross NumExplodingSheep/],
  date      => [qw/OpeningDate/],
);

# Later on, over in another package ...

my $h = CGI::Untaint->new( ... );
my $film = Film->retrieve('Godfather II');
   $film->update_from_cgi($h);

my $new_film = Film->create_from_cgi($h);

if (my %errors = $film->cgi_update_errors) {
  while (my ($field, $problem) = each %errors) {
    warn "Problem with $field: $problem\n";
  }
}

# or
$film->update_from_cgi($h => @columns_to_update);

# or
$film->update_from_cgi($h => { ignore => \@cols_to_ignore,
                               required => \@cols_needed,
                               all => \@columns_which_may_be_empty });

my $how = $film->untaint_type('Title'); # printable

πŸ¦‹ DESCRIPTION πŸ¦‹

so like, a LOT of the time, Class::DBI is used in web-based applications. (and honestly, when you pair it with a templating system that lets you pass objects around β€” think Template::Toolkit β€” Class::DBI is genuinely your bestie for that kind of thing.) ✨

and as we all know, the most irritating part of writing web apps is the absolute monotony of writing the same stuff over and over again 😭 and where there's monotony, there's the very real temptation to skip the stuff we all know is important but is a total pain to write β€” like Taint Checking and sensible input validation. (especially because you can still show a "working" application without any of it!) πŸ’€ so yeah, that's why CGI::Untaint exists, to take care of a lot of that for us.

and plot twist: CGI::Untaint also plays super nicely with Class::DBI. Class::DBI::FromCGI is a little wrapper that ties these two together πŸ’–


πŸ‘‘ METHODS πŸ‘‘

πŸŽ€ untaint_columns

all you gotta do is use Class::DBI::FromCGI in your class (or in your local Class::DBI subclass that all your other classes inherit from β€” you do do that, right? πŸ™ˆ).

then, in every class where you wanna use this, you declare how you want each column untainted:

__PACKAGE__->untaint_columns(
  printable => [qw/Title Director/],
  integer   => [qw/DomesticGross NumExplodingSheep/],
  date      => [qw/OpeningDate/],
);

(where the keys are the CGI::Untaint package you wanna use, and the values are a listref of the relevant columns πŸ’…)

πŸ’œ update_from_cgi

when you wanna update based on the values coming in from a web-based form, you just call:

$obj->update_from_cgi($h => @columns_to_update);

if every value passed in makes it through the CGI::Untaint process, the object gets updated (but not committed, in case you wanna do anything else with it, no cap). otherwise the update fails β€” and bestie, there are no partial updates β€” and $obj->cgi_update_errors will tell you what went wrong (as a hash of problem field => error from CGI::Untaint). πŸ”₯

🌈 create_from_cgi

same energy if you wanna create a new object, you can call:

my $obj = Class->create_from_cgi($h => @columns_to_update);

if this fails, $obj will be a defined object containing the errors, just like with an update β€” but it will not contain the values submitted, and it will not have been written to the database. 😀

🧚 untaint_type

my $how = $film->untaint_type('Title'); # printable

this tells you how we're gonna untaint a given column πŸ‘‘

⭐ cgi_update_errors

if (my %errors = $film->cgi_update_errors) {
  while (my ($field, $problem) = each %errors) {
    warn "Problem with $field: $problem\n";
  }
}

this returns a hash of any errors when updating. and despite its name, it also applies when inserting, so don't let the naming fool you πŸ’…


🌸 Column Auto-Detection 🌸

since Class::DBI knows all its columns, you don't even have to say which columns you're interested in β€” unless it's a subset, because we can auto-fill these for you:

$obj->update_from_cgi($h);

you can also specify columns that must be present, or columns to be ignored even if they are present:

$film->update_from_cgi($h => {
  all      => \@all_columns, # auto-filled if left blank
  ignore   => \@cols_to_ignore,
  required => \@cols_needed,
});

doesn't this all make your life so much easier? πŸ₯°


🚨 NOTE 🚨

do not try to update the value of your primary key. Class::DBI does not like that, like at all. if you try to do it, it will be silently skipped πŸ’€ (yes, silently β€” sneaky little thing).


πŸ™ˆ ANOTHER NOTE πŸ™ˆ

if you haven't set up any 'untaint_column' information for a column that you later attempt to untaint, then we try to call $self->column_type to figure out the default handler to use. currently this will only be used if you're using Class::DBI::mysql, and only for certain column types. iykyk 🫢


πŸ”— SEE ALSO πŸ”—

Class::DBI. CGI::Untaint. Template.


✍️ AUTHOR ✍️

Tony Bowden


πŸ› BUGS and QUERIES πŸ›

please direct all correspondence regarding this module to:

bug-Class-DBI-FromCGI@rt.cpan.org

Copyright (C) 2001-2005 Kasei. All rights reserved.

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


okay that's the whole thing bestie, you're so welcome πŸ’– and just so you know β€” this was rendered by perl v5.32.0 on 2021-01-05, and it's part of the User Contributed Perl Documentation collection. slay, periodt. πŸ‘‘βœ¨

πŸ“¦ where this page comes from