Question

A couple of notes before the question: I am by no means a programmer but I am tasked with getting this to work. I know the very basics and how to change a couple things from dabbling in it before but that's where my skillset ends. I have edited this to save space and make it as easy as possible. I know that this perl script is old but this is what I have to work with.

I have a form on an HTML page that has something like the following options:

<form action="/cgi-bin/form.pl" method="post" name="form">
    <input type="checkbox" name="morning_class" value="name1">
    <select name="Priority"><option value="">--Select--</option><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>


    <input type="checkbox" name="morning_class" value="name2">
    <select name="Priority"><option value="">--Select--</option><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>


    <input type="checkbox" name="morning_class" value="name3">
    <select name="Priority"><option value="">--Select--</option><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>


    <input type="checkbox" name="morning_class" value="name4">
    <select name="Priority"><option value="">--Select--</option><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>


    <input type="checkbox" name="morning_class" value="name5">
    <select name="Priority"><option value="">--Select--</option><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>

    <p><label class="field_pledge" for="fname">First Name:</label> <input maxlength="50" name="First_Name" size="32" type="text"></p>
    <p><label class="field_pledge" for="lname">Last Name:</label> <input maxlength="50" name="Last_Name" size="32" type="text"></p>
    <p><label class="field_pledge" for="email">EMail:</label> <input name="Email" size="32" type="text"></p>

    <p><input type="submit" value="Submit"> &nbsp; <input type="reset" value="Clear Form"></p>

</form>

I need the user to be limited to having to select exactly 3 selections from the checkboxes at the top. They must then list their priority options of which Morning Class they want to take in order from 1-3 (this is for scheduling reasons).

Currently, the Perl script is as follows (and as I've mentioned above, I know this is an old script but I'm stuck with it because this is what was given to me and I'm not a programmer):

#!/usr/bin/perl

#Variables
$queryString;
$contentLength;
$number;
$sendmail="/usr/sbin/sendmail";

@testarray;

%testhash;

$contentLength = $ENV{"CONTENT_LENGTH"};
$return = "/thankyou/";

if($contentLength != NULL){
    read(STDIN, $queryString, $contentLength);
}

@testarray = split(/&|=/,$queryString);

$number = @testarray;

for ($counter = 0; $counter <= $number; $counter++){
    @testarray[$counter] =~ s/\+/ /g;
    @testarray[$counter] =~ s/%([0-9A-Fa-f]{2})/pack("c",hex($1))/ge;
}

%testhash = @testarray;

##MESSAGE FORMATTING

$finalmailbody = "Title of Email - Registration Form\n\n";

$finalmailbody .= "First Name:  $testhash{First_Name}\n";
$finalmailbody .= "Last Name:   $testhash{Last_Name}\n";
$finalmailbody .= "Email:   $testhash{Email}\n";

##OPEN EMAIL AND SEND

open(MAILREGISTRATION, "|$sendmail -oi -t") || die  "Can't open pipe to $sendmail: $!\n";
print MAILREGISTRATION "To: me\@mywebsite.com\n";
print MAILREGISTRATION "From: $testhash{Email}\n"; 
print MAILREGISTRATION "Subject: Conference Submission\n\n";

print MAILREGISTRATION "$finalmailbody";
close(MAILREGISTRATION) or die "Can't close pipe to $sendmail: $!\n";

print "Content-type: text/html\n\n";
print "<HTML>\n";
print "<HEAD>\n";
print "  <META HTTP-EQUIV=Refresh CONTENT=0;URL=$return>\n";
print "</HEAD>\n";
print "<BODY>\n";
print "</BODY>\n";
print "</HTML>\n";

So, currently, what happens is once submitted, I get the following email:

First Name: (Info Entered)

Last Name: (Info Entered)

Email: (Info Entered)

The portion of where they input the data is not an issue. I know how to alter those lines and add more if needed.

This is where my issue occurs:

If i was to create a line in the message formatting like so:

$finalmailbody .= "Course 1:    $testhash{morning_class}\n";
$finalmailbody .= "Course 2:    $testhash{morning_class}\n";
$finalmailbody .= "Course 3:    $testhash{morning_class}\n";

All it does is email the last course that is selected like so:

Course 1: name3

Course 2: name3

Course 3: name3

Now I know that there needs to be some sort of code placed within the Perl script to sort the data that it has received from the (name=morning_class) data but this is where my knowledge limits me from going any further.

What I want in the end is to have the email that is sent to me display:

Course 1: name1 Priority: 3

Course 2: name2 Priority: 1

Course 3: name3 Priority: 2

First Name: (Info Entered)

Last Name: (Info Entered)

Email: (Info Entered)

The Perl portion is most important to me.

If this can be figured out, then I'd be open to suggestions of how to limit the selections to no more or less than 3 (I have something currently, but if there's a better way I'd like to see it), and how to tie in the Priority list to be sent in the email as well with the selected checkbox.

If there are any other questions that need to be answered let me know and I'll clear this up as best as I can.

I need all the help that I can so hopefully someone on here will be amazing and help me out. Thanks in advance!

Was it helpful?

Solution

It would be a lot easier if you use CGI, you can run into many problems processing parameters like this and it leaves your script vulnerable.

In your HTML you should associate each Priority menu with its checkbox, something like:

<input type="checkbox" name="morning_class" value="name2">
<select name="name2_Priority">

Then you can process like this:

my (%testhash,@classes);
while (my($name,$value) = splice(@testarray,0,2) ) {
    if ($name eq 'morning_class') {
        push(@classes,$value);
    }
    else {
        $testhash{$name} = $value;
    }
}
# remove any empty priority
@classes = grep { $testhash{$_.'_Priority'} } @classes; 
for my $class (@classes) {
    $testhash{$class} = $testhash{$class.'_Priority'};
}
# sort by priority
@classes = sort { $testhash{$a} <=> $testhash{$b} } @classes; 
# truncate array to 3 elements if necessary
$#classes = 2 if $#classes > 2;

Now you have in @classes an array of max 3 items sorted by priority, and the name of each class has its priority value in %testhash

Update: To print out the classes:

for my $class (@classes) {
    $mailbody .= "Course: $class Priority: $testhash{$class.'_Priority'}\n";
}

Update 2: for afternoon classes just add another array @aclasses:

my (%testhash,@classes,@aclasses);
while (my($name,$value) = splice(@testarray,0,2) ) {
    if ($name eq 'morning_class') {
        push(@classes,$value);
    }
    elsif ($name eq 'afternoon_class') {
        push(@aclasses,$value);
    }
    else {
        $testhash{$name} = $value;
    }
}

Now repeat everything you do to @classes only do it to @aclasses

OTHER TIPS

So a quick and dirty hack below. Note: In order for it to work, you would have to rename your html fields to morning_class1...morning_class5 and Priority1...Priority5. When you convert your list of values into a hash only one value can be associated with the key named 'morning_class' (e.g. the last one).

my @list =  map { $_ =~ /^Priority([\d]+)/; $1; }
    sort { $testhash{$a} <=> $testhash{$b}  }
    grep { $_ =~ /^Priority/ } keys %testhash;

@list = splice @list, 0, 3; # Take top 3 sorted

for(my $i=0; $i<scalar(@list); $i++) {
    $finalmailbody .= "Course " . ($i + 1) . ": " . $testhash{"morning_class${list[$i]}"} . ", Priority: " . $testhash{"Priority${list[$i]}"} . "\n";
}

If I were writing this rather than hacking on it, though, there are quite a few things I would do differently. I would add some validation using client-side script so that your Perl is never getting more than 3 choices. Even if this is working a user could set the same priority to each selection so sorting them would be meaningless.

Note: I just realized you didn't ask for them to be sorted by priority but that is how I wrote it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top