package Comments;
# gets comments form parameters, generates comments form
#
use Exporter;
@ISA = qw(Exporter);
use strict;
use CGI;
use CGI::Carp qw( fatalsToBrowser);
# processes POST data from a comments form sent to the program
# create a new object
# to determine if data has been received call commentReceived()
sub new {
# calling sequence
# CommentsProcessingObj->new($cgiObj)
# start by getting data we can't get later
my $invocant = shift @_;
my $className = ref($invocant) || $invocant;
my $self = {};
bless ($self, $className);
# and our cgi object
my $cgiObj = shift;
# check whether we've received any post
$self->{COMMENT_RECEIVED} = undef;
my @listOfParamsReceived = $cgiObj->param();
foreach my $elem (@listOfParamsReceived) {
if ( $elem eq "text" ) {
$self->{COMMENT_RECEIVED} = 1;
} # end if
} # end foreach
# whether we've had post or not
# I like all relevant parameters to be initialised
$self->{TEXT} = $cgiObj->param('text');
$self->{TEXT_ERRORS} = undef;
$self->{TEXT_DIAGNOSTIC} = undef;
$self->{CGI_OBJ} = $cgiObj;
if ( ! $self->{COMMENT_RECEIVED} ) {
return $self;
} # end if
validate($self);
return $self;
} # end new
sub commentReceived {
my $self = shift;
return $self->{COMMENT_RECEIVED};
} # end commentReceived
sub text {
my $self = shift;
return $self->{TEXT};
} # end getText
sub textErrors {
my $self = shift;
return $self->{TEXT_ERRORS};
} # end getTextErrors
sub textDiagnostic {
my $self = shift;
return $self->{TEXT_DIAGNOSTIC};
} # end textDiagnostic
# private
sub validate {
my $self = shift;
if ( ! $self->{TEXT} ) {
$self->{TEXT_ERRORS} = 1;
$self->{TEXT_DIAGNOSTIC} = "empty text field";
return;
} #end if
if ( allSpaces($self->{TEXT}) ) {
$self->{TEXT_ERRORS} = 1;
$self->{TEXT_DIAGNOSTIC} = "empty text";
return;
} #end if
if ( ! validCharacters($self->{TEXT}) ) {
$self->{TEXT_ERRORS} = 1;
$self->{TEXT_DIAGNOSTIC} = "Text contains invalid characters";
} #end if
return;
} # end validate
# private
sub allSpaces {
my $pMessage = shift;
if ($pMessage =~ /\A\s+\z/) { return 1; } # nothing there but spaces, tabs or new lines
return undef;
} # end allSpaces
# private
sub validCharacters {
my $pMessage = shift;
# we allow the inclusion of all printable characters
# where necessary we convert these into HTML character entities
# Needs updating to allow unicode character set
# the message consists of a set of lines terminated by returns, line feeds etc
# we allow the inclusion of e-mail addresses and hence the e-mail character set
my $esc = '\\\\';
my $ctrl1 = '\000-\011'; # \007 = bell, \010 = backspace, \011 = horiz tab
# \012 = line feed
my $ctrl2 = '\013\014'; # \013 = vertical tab, \014 = form feed
# \015 = carriage return
my $ctrl3 = '\016-\037'; # other non-printing chars
my $del = '\0127'; # del
my $nonASCII = '\x80-\xff'; # 128 - 255
my $unwantedChars = "$ctrl1$ctrl2$ctrl3$esc$del"."\^\$";
if ($pMessage =~ /$unwantedChars/) { return undef; }
if ($pMessage =~ /~!/) { return undef; } # major threat at start of line, don't allow it at all
return 1;
} # end validCharacters
############## form generation ####################
# public
sub setCommentsFormText {
# returns html code representing the comments form, including the text visitor entered into it previously
# called from anypage.pl
# calling sequence my $text = $commentsObj->setStandardComments($pictureGroup,$pageFileName);
my $self = shift;
my $groupName = shift;
my $pageFileName = shift;
my $textSentlastTime = $self->text();
my $commentFieldAndText = "<label for='your_comment_text'>your comments </label>";
$commentFieldAndText .= "<textarea id='your_comment_text' name='text' rows='5' cols='30'>$textSentlastTime</textarea>";
my $sendButtonAndText = "If you include your e-mail I may reply! <input type='submit' value='send' />";
my $commentHeading = "";
if ( $self->textErrors() ) {
$commentHeading = "<h3 class='commentErrors'>Error:". $self->textDiagnostic() . "</h3>";
$commentHeading .= "<p class='commentErrors'> please try again.</p>";
} elsif ( $self->commentReceived() ) {
# i.e. the comment was received ok
$commentHeading = "<h3 class='commentSetOk'>Thank you</h3>";
# I do this to prevent people just sitting there clicking the send button
$commentFieldAndText = "<label for='text'>What you wrote I now have in my inbox</label>";
$commentFieldAndText .= "<textarea name='text' rows='5' cols='30'>$textSentlastTime</textarea>";
$sendButtonAndText = "<p class='commentComment'>If you included your e-mail I may reply!</p>";
} # end if
my $text = <<FORM;
<a name='commentsForm'> </a>\n
<form name="comments_form" action="http://yourWebsiteDotCom/cgi-bin/gnu/$groupName/$pageFileName#commentsForm" method="post">
<h3>Send me your comments</h3>
$commentHeading
<p>
$commentFieldAndText
</p>
<p>
$sendButtonAndText
</p>
</form>
FORM
return $text;
} # end setCommentsFormText
1;