Gossamer Forum
Home : General : Perl Programming :

Easy Perl Question

Quote Reply
Easy Perl Question
I have made a cgi feedback form for my website and before it prints the success page and sends an email I want the script to check for blank fields so I have added the following code:

if ($name eq "") {
&error();
}
if ($email eq "") {
&error();
}
if ($sitename eq "") {
&error();
}
if ($siteurl eq "") {
&error();
}
if ($sitedesc eq "") {
&error();
}
if ($banner eq "") {
&error();
}
if ($pass eq "") {
&error();
}
if ($contract eq "") {
&error();
}
if ($click eq "") {
&error();
}
if ($imp eq "") {
&error();
}
exit;


In &error(); is the following:

sub error {
print "Content-type: text/html \n\n";

print qq|
You forgot to fill in some fields!<BR>
|;
}


If the name field is the only blank one then this is ok as it says "You forgot to fill in some fields".

However if more than one field is blank it says "You forgot to fill in some fields!" for EACH blank field so the page looks like:

You forgot to fill in some fields!
You forgot to fill in some fields!
You forgot to fill in some fields!
You forgot to fill in some fields!

...and it also prints out: Content-type: text/html \n\n

So the error page ends up looking like:

You forgot to fill in some fields!Content-type: text/html \n\n
You forgot to fill in some fields!Content-type: text/html \n\n
You forgot to fill in some fields!Content-type: text/html \n\n
You forgot to fill in some fields!Content-type: text/html \n\n


How do I get around this?


Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
take the links approach....

my (@errors);

if ($name eq "") {
push (@errors, "Name");
}
etc...
etc...
etc...

if (@errors > 0) {
&error (@errors);
}

sub error {
my (@errors) = @_;
print "Content-type: text/html\n\n";
print "You forgot to fill in:
\n";
foreach (@error) {
print " $_
\n";
}
}

Jerry Su
widgetz sucks
Quote Reply
Re: Easy Perl Question In reply to
Oh right...thanks.

I actually came up with something that I found a little easier to understand.
Maybe Im being thick but that code you provided is a bit over my head!

Im using :

@required = ('Name','Email','SiteName','SiteDescription','SiteURL','BannerURL','Password');

foreach $check(@required) {
unless ($FORM{$check}) {
print "Content-type: text/html\n\n";
print "<html><head><title>Submission Failure</title></head>\n";
print "<body><h2>Submission Failure</h2>
\n";
print "Sorry, you forgot to\n";
print "fill in the $check field.<p><BR>\n\n";
print "<a href=\"javascript:history.go(-1)\">Go Back</a>";
print "</body></html>\n";
exit;
}
}


Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
I just took another look at the code you provided and it is not as complicated as I thought!

Im learning every day!

How about this question:

I have got someone to put my banner on their main page and it is pointing to my "Domain Name Selling" page.

When someone buys a domain after being referred from the person displaying my banner I would like the email that is sent to me when they register to include the referers url so I can see how many people they have referred because I am paying them commission for each domain sold as a result of a referal from their site.

I think the only way is to get the banner to link to a perl script that creates a cookie and then forwards them to the registration page.

Then, I need to get the formmail script to retrieve the cookie value and mail it to me with the rest of the domain name info.

How the heck do I do that?

I have this so far for the first page:

#!/usr/bin/perl

&cookie();
&main();

sub cookie {
my $cookie=cookie( -name => Audio,
-value => $ENV{'REFERER'},
-expires => +30d,
-secure => false
);

}

sub main {
print "Content-type: text/html \n\n";
print qq|<html>
<head>
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=http://www.audio-grabber.com/domains/">
</head>
<body>
</body>
</html>
|;
}


Does this look ok?

Now how would I retrieve the cookie in a different script and get the value mailed to me with the rest of the signup info.

Would I use...

$cookie_value=cookie('Audio');

print MAIL "$cookie_value";


????

Thanks!

Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
EUGH.....

This code..

#!/usr/bin/perl


&cookie();
&main();

sub cookie {
my $cookie=cookie( -name => Audio,
-value => $ENV{'REFERER'},
-secure => false
);

}

sub main {
print "Content-type: text/html \n\n";
print qq|<html>
<head>
<META HTTP-EQUIV="Refresh" CONTENT="0;URL=http://www.audio-grabber.com/domains/">
</head>
<body>
</body>
</html>
|;
}


...makes the page hang or freeze. Whats causing that?

I had to remove -expires => +30d, because that was causing an Internal Server Error.



Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
lol....

you call cookie in cookie.. that makes an infinite loop..

second.. looks like you don't know how to make cookies either..

to set a cookie.. you print out the information.. i don't have this on the top of my head.. its probably like

Set-Cookie: NAME=VALUE; expiries=; path=/; domain=DOMAIN; secure\n

Jerry Su
widgetz sucks
Quote Reply
Re: Easy Perl Question In reply to
oh and btw.. the thing about your error checking thing is that you can only check the first error.. there can be 5 unfilled textfields and you can only return the first one..

mine (or the way links does it) you check all fields to see if they are filled in... if there is 5 missing.. it will print out that those five were missing..

Jerry Su
widgetz sucks
Quote Reply
Re: Easy Perl Question In reply to
Well we all have to learn somewhere :)



Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
Oh right thanks....I will change the error code to the example you provided if it can list all errors at once.


Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
erm....you know how you said I didnt know how to make cookies?

Well this is what I found at activestate....


use CGI qw/:standard/;
use CGI::Cookie;

# Create new cookies and send them

$cookie1 = new CGI::Cookie(-name=>'ID',-value=>123456);

$cookie2 = new CGI::Cookie(-name=>'preferences',
-value=>{ font => Helvetica,
size => 12 }
);

print header(-cookie=>[$cookie1,$cookie2]);


That is similar to what I wrote isnt it?

Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
Right...Im getting further....

Why doesnt this code work please?

#!/usr/bin/perl

use CGI qw/:standard/;
use CGI::Cookie;

if ($ENV{'REQUEST_METHOD'} eq 'GET') {
$buffer = $ENV{'QUERY_STRING'};
}
else {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}

# Break em up into a format the script can read

@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}

$action = $FORM{audiograbber};

if ($action eq "go") { &color(); } else { &start(); }

sub start{
print "Content-Type: text/html\n\n";

print qq|
<html>
<head>
</head>
<body bgcolor="#999999">
<form action="cookie.cgi" method="GET">
<input type="hidden" name="audiograbber" value="go">
<select name="color">
<option value="#ffffff">White
<option value="#ff3333">Red
</select>
<input type="submit" value="Submit!">
</FORM>
</body>
</html>
|;

}



sub color {
$value = $FORM{'color'};
$d = new CGI::Cookie( -name => 'bg',
-value => '$value',
-expires => '+1M',
-domain => '.audio-grabber.com',
-secure => 0
);

print "Set-Cookie: $d\n";
print "Content-Type: text/html\n\n";
$d = cookie('color');

print qq|
<html>
<head>
</head>
<body bgcolor="$d">
The background color has now been changed!
</body>
</html>
|;

}


It all works ok except the bgcolor doesnt change to the color selected on the first page.

Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
$d = cookie('color');

umm.. cookie('color'); isn't defined..

if you really want to use cookies.. i suggest you use a cookie library or use CGI.pm...

ie:

use CGI ();
my $in = new CGI;
my $color = $in->cookie ('color');

at activestate the CGI.pm documentation tells you how to set cookies..

Jerry Su
widgetz sucks
Quote Reply
Re: Easy Perl Question In reply to
Thanks...I may have to change the habit of a lifetime and do some reading!

Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
OH DUH....how thick am I....

Should have been $d = cookie('bg');

...not...

$d = cookie('color');

Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
lol....

I just took a look at the CGI.pm documentation and I realised that I had actually already read that info earlier today!

Guess I'll have to keep practicing with cookies!

Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
Ack, stay away from the function based style of CGI.pm and use the OO style. Your script should really look like:

Code:
#!/usr/bin/perl -w

use CGI;
use strict;

my $in = new CGI;
my $action = $in->param('action') || '';
if ($action eq 'go') {
color();
}
else {
start();
}

sub start {
print $in->header;
print qq~
<html>
<head>
</head>
<body bgcolor="#999999">
<form action="cookie.cgi" method="GET">
<input type="hidden" name="audiograbber" value="go">
<select name="color">
<option value="#ffffff">White
<option value="#ff3333">Red
</select>
<input type="submit" value="Submit!">
</FORM>
</body>
</html>
~;
}

sub color {
my $color = $in->param('color');
my $cookie = $in->cookie (
-name => 'bg',
-value => $color,
-expires => '+1M',
-domain => '.audio-grabber.com',
-secure => 0
);
print $in->header ( -cookie => $cookie );
print qq~
<html>
<head>
</head>
<body bgcolor="$color">
The background color has now been changed!
</body>
</html>
~;

}
Cheers,

Alex

--
Gossamer Threads Inc.
Quote Reply
Re: Easy Perl Question In reply to
Thanks....whats the 00 style by the way?

This...

<input type="hidden" name="audiograbber" value="go">

...should be changed to this as well shouldnt it?

<input type="hidden" name="action" value="go">

Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
Oops, yes, that's correct. The OO (object oriented) style is using an object for everything. So instead of:

my $color = cookie('bg');

Do:

my $color = $in->cookie('bg');

It may not seem like a big deal, but it will make your code more readable in the future as it gets larger.

Cheers,

Alex

--
Gossamer Threads Inc.
Quote Reply
Re: Easy Perl Question In reply to
Thanks for the tip!

Is there any difference between $in and $IN ??

Or is it just literally uppercase and lowercase?



Paul Wilson. Shocked
(Dont blame me if I'm wrong!)
Quote Reply
Re: Easy Perl Question In reply to
Hi,

We use all caps to represent variables that are global, so it's purely for style, no difference to perl.

Cheers,

Alex

--
Gossamer Threads Inc.