line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
package CGI::Application::Mailform; |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
# Always use strict! |
5
|
1
|
|
|
1
|
|
105701
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
32
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
# This is a CGI::Application module |
9
|
1
|
|
|
1
|
|
698
|
use CGI::Application; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
44
|
|
10
|
|
|
|
|
|
|
@CGI::Application::Mailform::ISA = qw/CGI::Application/; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# Required, but not enforced by Makefile.PL! |
14
|
1
|
|
|
1
|
|
10
|
use Net::SMTP; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
46
|
|
15
|
1
|
|
|
1
|
|
6
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
1268
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
############################################# |
20
|
|
|
|
|
|
|
## OVERRIDE METHODS |
21
|
|
|
|
|
|
|
## |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# Run when new() is called |
24
|
|
|
|
|
|
|
sub setup { |
25
|
1
|
|
|
1
|
1
|
1
|
my $self = shift; |
26
|
|
|
|
|
|
|
|
27
|
1
|
|
|
|
|
4
|
$self->mode_param('rm'); |
28
|
1
|
|
|
|
|
3
|
$self->start_mode('showform'); |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
# Set up run-mode table. In a typical CGI::Application module, this would |
31
|
|
|
|
|
|
|
# contain multiple run-modes -- one for each think your app can do. |
32
|
|
|
|
|
|
|
# We're using sub-ref instead of name-ref to display more intuitive errors. |
33
|
|
|
|
|
|
|
# |
34
|
1
|
|
|
|
|
6
|
$self->run_modes( |
35
|
|
|
|
|
|
|
'showform' => \&redirect_to_mailform, |
36
|
|
|
|
|
|
|
'submitform' => \&submitform_and_sendmail, |
37
|
|
|
|
|
|
|
); |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Called when run() is called. |
42
|
|
|
|
|
|
|
sub cgiapp_prerun { |
43
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
44
|
0
|
|
|
|
|
|
my $runmode = shift; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# Make sure the instance script is correct |
47
|
0
|
|
|
|
|
|
$self->validate_runtime(); |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
############################################# |
53
|
|
|
|
|
|
|
## RUN-MODE METHODS |
54
|
|
|
|
|
|
|
## |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
sub redirect_to_mailform { |
57
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
# Set up the HTTP redirect |
60
|
0
|
|
|
|
|
|
my $redirect_url = $self->param('HTMLFORM_REDIRECT_URL'); |
61
|
|
|
|
|
|
|
|
62
|
0
|
|
|
|
|
|
return $self->do_redirect($redirect_url); |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
sub submitform_and_sendmail { |
67
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# Actually send out the email message |
70
|
0
|
|
|
|
|
|
$self->sendmail(); |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# Set up the HTTP redirect |
73
|
0
|
|
|
|
|
|
my $redirect_url = $self->param('SUCCESS_REDIRECT_URL'); |
74
|
|
|
|
|
|
|
|
75
|
0
|
|
|
|
|
|
return $self->do_redirect($redirect_url); |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
############################################# |
81
|
|
|
|
|
|
|
## PRIVATE METHODS |
82
|
|
|
|
|
|
|
## |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
# Perform an HTTP redirect |
85
|
|
|
|
|
|
|
sub do_redirect { |
86
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
87
|
0
|
|
|
|
|
|
my $redirect_url = shift; |
88
|
|
|
|
|
|
|
|
89
|
0
|
|
|
|
|
|
$self->header_type( 'redirect' ); |
90
|
0
|
|
|
|
|
|
$self->header_props( -url => $redirect_url ); |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# Return HTML to the web browser |
93
|
0
|
|
|
|
|
|
my $redirect_html = "Continue: $redirect_url"; |
94
|
0
|
|
|
|
|
|
return $redirect_html; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# This method is to verify that the instance script (i.e., "mailform.cgi") |
99
|
|
|
|
|
|
|
# contains the correct configuration parameters. |
100
|
|
|
|
|
|
|
sub validate_runtime { |
101
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
## CHECK REQUIRED PARAMETERS |
104
|
|
|
|
|
|
|
# |
105
|
0
|
|
|
|
|
|
my $req_failed = 0; |
106
|
|
|
|
|
|
|
|
107
|
0
|
|
|
|
|
|
my @required_params = qw/ |
108
|
|
|
|
|
|
|
MAIL_FROM |
109
|
|
|
|
|
|
|
MAIL_TO |
110
|
|
|
|
|
|
|
HTMLFORM_REDIRECT_URL |
111
|
|
|
|
|
|
|
SUCCESS_REDIRECT_URL |
112
|
|
|
|
|
|
|
FORM_FIELDS |
113
|
|
|
|
|
|
|
/; |
114
|
|
|
|
|
|
|
|
115
|
0
|
|
|
|
|
|
foreach my $req_param (@required_params) { |
116
|
|
|
|
|
|
|
# Check each req param to verify that it is there |
117
|
0
|
0
|
0
|
|
|
|
unless ( defined($self->param($req_param)) && length($self->param($req_param)) ) { |
118
|
0
|
|
|
|
|
|
$req_failed++; |
119
|
0
|
|
|
|
|
|
carp("Required parameter '$req_param' not specified"); |
120
|
|
|
|
|
|
|
} else { |
121
|
|
|
|
|
|
|
# Especially check that FORM_FIELDS is an array-ref |
122
|
0
|
0
|
0
|
|
|
|
if (($req_param eq 'FORM_FIELDS') && (ref($self->param('FORM_FIELDS')) ne 'ARRAY')) { |
123
|
0
|
|
|
|
|
|
$req_failed++; |
124
|
0
|
|
|
|
|
|
carp("Required parameter 'FORM_FIELDS' is not an array reference"); |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# Die if we have an invalid run-time configuration |
131
|
0
|
0
|
|
|
|
|
croak("Missing or invalid required parameters") if ($req_failed); |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
## CHECK OPTIONAL PARAMETERS / SET DEFAULT VALUES |
135
|
|
|
|
|
|
|
# |
136
|
0
|
|
|
|
|
|
my $opt_failed = 0; |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
## ENV_FIELDS |
139
|
|
|
|
|
|
|
# If undefined, define as null |
140
|
0
|
0
|
|
|
|
|
$self->param('ENV_FIELDS', []) unless (defined($self->param('ENV_FIELDS'))); |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# Now, check for validity |
143
|
0
|
0
|
|
|
|
|
unless (ref($self->param('ENV_FIELDS')) eq 'ARRAY') { |
144
|
0
|
|
|
|
|
|
$opt_failed++; |
145
|
0
|
|
|
|
|
|
carp("Parameter 'ENV_FIELDS' is not an array reference"); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
## SUBJECT |
149
|
0
|
|
|
|
|
|
my $subject = $self->param('SUBJECT'); |
150
|
0
|
0
|
0
|
|
|
|
unless (defined($subject) && length($subject)) { |
151
|
0
|
|
0
|
|
|
|
$subject = 'Form submission from ' . ($ENV{HTTP_REFERER} || $ENV{SCRIPT_NAME}); |
152
|
0
|
|
|
|
|
|
$self->param('SUBJECT', $subject); |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
## SMTP_HOST |
156
|
0
|
0
|
|
|
|
|
$self->param('SMTP_HOST', '') unless (defined($self->param('SMTP_HOST'))); |
157
|
|
|
|
|
|
|
# Expect a scalar for SMTP_HOST. Other values will be deemed errors, |
158
|
|
|
|
|
|
|
# to prevent problems when interfacing with Net::SMTP. |
159
|
0
|
0
|
|
|
|
|
unless (ref($self->param('SMTP_HOST')) eq '') { |
160
|
0
|
|
|
|
|
|
$opt_failed++; |
161
|
0
|
|
|
|
|
|
carp("Parameter 'SMTP_HOST' is not a scalar"); |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# Die if we have an invalid run-time configuration |
165
|
0
|
0
|
|
|
|
|
croak("Invalid optional parameters") if ($opt_failed); |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# Establish SMTP connection |
170
|
|
|
|
|
|
|
sub connect_smtp { |
171
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
172
|
|
|
|
|
|
|
|
173
|
0
|
|
|
|
|
|
my $smtp_host = $self->param('SMTP_HOST'); |
174
|
|
|
|
|
|
|
|
175
|
0
|
|
|
|
|
|
my $smtp_connection; |
176
|
|
|
|
|
|
|
|
177
|
0
|
0
|
|
|
|
|
if (length($smtp_host)) { |
178
|
|
|
|
|
|
|
# Use provided host |
179
|
0
|
|
|
|
|
|
$smtp_connection = Net::SMTP->new($smtp_host); |
180
|
0
|
0
|
|
|
|
|
croak("Unable to connect to '$smtp_host'") |
181
|
|
|
|
|
|
|
unless (defined($smtp_connection)); |
182
|
|
|
|
|
|
|
} else { |
183
|
|
|
|
|
|
|
# Use default host |
184
|
0
|
|
|
|
|
|
$smtp_connection = Net::SMTP->new(); |
185
|
0
|
0
|
|
|
|
|
croak("Unable to establish SMTP connection") |
186
|
|
|
|
|
|
|
unless (defined($smtp_connection)); |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
0
|
|
|
|
|
|
return $smtp_connection; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
# This method actually generates and sends the email message via |
194
|
|
|
|
|
|
|
# SMTP, or die()s trying. |
195
|
|
|
|
|
|
|
sub sendmail { |
196
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# Get the CGI query object |
199
|
0
|
|
|
|
|
|
my $q = $self->query(); |
200
|
|
|
|
|
|
|
|
201
|
0
|
|
|
|
|
|
my $mailfrom = $self->param('MAIL_FROM'); |
202
|
0
|
|
|
|
|
|
my $mailto = $self->param('MAIL_TO'); |
203
|
0
|
|
|
|
|
|
my $subject = $self->param('SUBJECT'); |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
# Get the message body |
206
|
0
|
|
|
|
|
|
my $msgbody = $self->build_msgbody(); |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Connect to SMTP server |
209
|
0
|
|
|
|
|
|
my $smtp_connection = $self->connect_smtp(); |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# Here's where we "do the deed"... |
212
|
0
|
|
|
|
|
|
$smtp_connection->mail($mailfrom); |
213
|
0
|
|
|
|
|
|
$smtp_connection->to($mailto); |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
# Enter data mode |
216
|
0
|
|
|
|
|
|
$smtp_connection->data(); |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
# Send the message content (header + body) |
219
|
0
|
|
|
|
|
|
$smtp_connection->datasend("From: $mailfrom\n"); |
220
|
0
|
|
|
|
|
|
$smtp_connection->datasend("To: $mailto\n"); |
221
|
0
|
|
|
|
|
|
$smtp_connection->datasend("Subject: $subject\n"); |
222
|
0
|
|
|
|
|
|
$smtp_connection->datasend("\n"); |
223
|
0
|
|
|
|
|
|
$smtp_connection->datasend($msgbody); |
224
|
0
|
|
|
|
|
|
$smtp_connection->datasend("\n"); |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# Exit data mode |
227
|
0
|
|
|
|
|
|
$smtp_connection->dataend(); |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
# Be polite -- disconnect from the server! |
231
|
0
|
|
|
|
|
|
$smtp_connection->quit(); |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
# Here's where the majority of the work gets done. |
236
|
|
|
|
|
|
|
# Based on the settings in the instance script and |
237
|
|
|
|
|
|
|
# the CGI form data, an email message body is created. |
238
|
|
|
|
|
|
|
sub build_msgbody { |
239
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# Get the CGI query object |
242
|
0
|
|
|
|
|
|
my $q = $self->query(); |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
# The longest journey begins with a single step... |
245
|
0
|
|
|
|
|
|
my $msgbody = ''; |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
## Populate message body with form data |
248
|
|
|
|
|
|
|
# |
249
|
0
|
|
|
|
|
|
my $form_fields = $self->param('FORM_FIELDS'); |
250
|
0
|
|
|
|
|
|
my $ff_count = 1; |
251
|
0
|
|
|
|
|
|
$msgbody .= "The following data has been submitted:\n\n"; |
252
|
0
|
|
|
|
|
|
foreach my $field (@$form_fields) { |
253
|
0
|
|
|
|
|
|
$msgbody .= "$ff_count\. $field\:\n" . $self->clean_data($q->param($field)). "\n\n\n"; |
254
|
0
|
|
|
|
|
|
$ff_count++; |
255
|
|
|
|
|
|
|
} |
256
|
0
|
|
|
|
|
|
$msgbody .= "\n"; |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
## Populate message body with environment data |
259
|
|
|
|
|
|
|
# |
260
|
0
|
|
|
|
|
|
my $env_fields = $self->param('ENV_FIELDS'); |
261
|
|
|
|
|
|
|
# Do we actually have any env data requested? |
262
|
0
|
0
|
|
|
|
|
if (@$env_fields) { |
263
|
0
|
|
|
|
|
|
my $ef_count = 1; |
264
|
0
|
|
|
|
|
|
$msgbody .= "Form environment data:\n\n"; |
265
|
0
|
|
|
|
|
|
foreach my $field (@$env_fields) { |
266
|
0
|
|
|
|
|
|
$msgbody .= "$ef_count\. $field\:\n" . $self->clean_data($ENV{$field}). "\n\n\n"; |
267
|
0
|
|
|
|
|
|
$ef_count++; |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
# Send back the complete message body |
272
|
0
|
|
|
|
|
|
return $msgbody; |
273
|
|
|
|
|
|
|
} |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
# This method cleans up data for inclusion into the email message |
277
|
|
|
|
|
|
|
sub clean_data { |
278
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
279
|
0
|
|
|
|
|
|
my $field_data = shift; |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
# Set undef strings to a null string |
282
|
0
|
0
|
|
|
|
|
$field_data = '' unless (defined($field_data)); |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
# Strip leading & trailing white space |
285
|
0
|
|
|
|
|
|
$field_data =~ s/^\s*//; |
286
|
0
|
|
|
|
|
|
$field_data =~ s/\s$//; |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
# If we have no answer, put "[n/a]" in there. |
289
|
0
|
0
|
|
|
|
|
$field_data = '[n/a]' unless (length($field_data)); |
290
|
|
|
|
|
|
|
|
291
|
0
|
|
|
|
|
|
return $field_data; |
292
|
|
|
|
|
|
|
} |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
############################################# |
299
|
|
|
|
|
|
|
## POD |
300
|
|
|
|
|
|
|
## |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=pod |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
=head1 NAME |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
CGI::Application::Mailform - |
307
|
|
|
|
|
|
|
A simple HTML form to email system |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
=head1 SYNOPSIS |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
## In "mailform.cgi" -- |
313
|
|
|
|
|
|
|
use CGI::Application::Mailform; |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
# Create a new Mailform instance... |
316
|
|
|
|
|
|
|
my $mf = CGI::Application::Mailform->new(); |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
# Configure your mailform |
319
|
|
|
|
|
|
|
$mf->param('MAIL_FROM' => 'webmaster@your.domain'); |
320
|
|
|
|
|
|
|
$mf->param('MAIL_TO' => 'form_recipient@your.domain'); |
321
|
|
|
|
|
|
|
$mf->param('HTMLFORM_REDIRECT_URL' => '/uri/or/url/to/mailform.html'); |
322
|
|
|
|
|
|
|
$mf->param('SUCCESS_REDIRECT_URL' => '/uri/or/url/to/thankyou.html'); |
323
|
|
|
|
|
|
|
$mf->param('FORM_FIELDS' => [qw/name address comments etc/]); |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# Optional variables |
326
|
|
|
|
|
|
|
$mf->param('SMTP_HOST' => 'mail.your.domain'); |
327
|
|
|
|
|
|
|
$mf->param('SUBJECT' => 'New form submission'); |
328
|
|
|
|
|
|
|
$mf->param('ENV_FIELDS' => [qw/REMOTE_ADDR HTTP_USER_AGENT/]); |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
# Now run... |
331
|
|
|
|
|
|
|
$mf->run(); |
332
|
|
|
|
|
|
|
exit(0); |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
## In "mailform.html" -- |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
## In "thankyou.html" -- |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
Thanks for your submission! It has been sent. |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
=head1 DESCRIPTION |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
CGI::Application::Mailform is a reusable and customizable mailform |
355
|
|
|
|
|
|
|
for the web. It is intentionally simple, and provides very few facilities. |
356
|
|
|
|
|
|
|
What it does do is provide an easy-to-use, secure system for taking the contents |
357
|
|
|
|
|
|
|
of a HTML form submission and sending it, via email, to a specified recipient. |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
This module was created as an example of how to use CGI::Application, a |
360
|
|
|
|
|
|
|
framework for creating reusable web-based applications. In addition to |
361
|
|
|
|
|
|
|
providing a simple example of CGI::Application's usage, |
362
|
|
|
|
|
|
|
CGI::Application::Mailform is also a fully functional application, |
363
|
|
|
|
|
|
|
capable of running in a production environment. |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
Just as is the case with any web-application built upon CGI::Application, |
366
|
|
|
|
|
|
|
CGI::Application::Mailform will run on any web server and operating system |
367
|
|
|
|
|
|
|
which supports the Common Gateway Interface (CGI). It will run equally |
368
|
|
|
|
|
|
|
well on Apache as it runs on IIS or the iPlanet server. It will run |
369
|
|
|
|
|
|
|
perfectly well on UNIX, Linux, Solaris or Windows NT. It will take full |
370
|
|
|
|
|
|
|
advantage of the advanced capabilities of MOD_PERL. It will probably |
371
|
|
|
|
|
|
|
even run under FastCGI (although the author has not personally tested it |
372
|
|
|
|
|
|
|
in that environment). |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head2 USAGE |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
Once CGI::Application::Mailform has been installed, you must complete the |
379
|
|
|
|
|
|
|
following steps to create a custom mailform on your website: |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
1. Create 'mailform.html' |
382
|
|
|
|
|
|
|
2. Create 'thankyou.html' |
383
|
|
|
|
|
|
|
3. Create 'mailform.cgi' |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
Examples of these files are provided in the directory "Examples" |
386
|
|
|
|
|
|
|
which can be found in the installation tar file for CGI::Application. |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
=head2 Create 'mailform.html' |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
The file 'mailform.html' is simply an HTML file which contains your web form. |
392
|
|
|
|
|
|
|
This is the form whose contents will be sent, via CGI::Application::Mailform, |
393
|
|
|
|
|
|
|
to the specified recipient's email address. |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
This file need only contain the basic HTML form. There are two requirements |
396
|
|
|
|
|
|
|
for this form. First, the "action" attribute of the |
397
|
|
|
|
|
|
|
CGI instance script ('mailform.cgi') you are about to create. Second, |
398
|
|
|
|
|
|
|
the form must set a "hidden" form field with the name "rm" and the value "submitform". |
399
|
|
|
|
|
|
|
This hidden parameter is what tells the CGI::Application::Mailform application to send the |
400
|
|
|
|
|
|
|
email message, as opposed to send the user to the HTML form. |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
For example: |
403
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
Your 'mailform.html' may also contain JavaScript to provide form validation. |
410
|
|
|
|
|
|
|
The CGI::Application::Mailform does not (currently) have any internal form |
411
|
|
|
|
|
|
|
validation capabilities. As described earlier, this is a very simple system. |
412
|
|
|
|
|
|
|
If it is necessary to enforce any fields as "required", it is recommended that |
413
|
|
|
|
|
|
|
JavaScript be used. |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
NOTE: It is not necessary that your HTML file be called 'mailform.html'. |
416
|
|
|
|
|
|
|
You may name this file anything you like. The only naming limitation is that the name of this |
417
|
|
|
|
|
|
|
file should be correctly referenced in your 'mailform.cgi', in the variable 'HTMLFORM_REDIRECT_URL'. |
418
|
|
|
|
|
|
|
|
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=head2 Create 'thankyou.html' |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
The next file you need to create is your 'thankyou.html' file. This file is the |
425
|
|
|
|
|
|
|
simplest of all. This is the file to which users will be redirected once they have |
426
|
|
|
|
|
|
|
successfully submitted their form data. The purpose of this screen is to inform |
427
|
|
|
|
|
|
|
and assure the user that their form data submission has been successfully received |
428
|
|
|
|
|
|
|
and processed. |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
For example: |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
Thank you! |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
Thanks for your submission! |
438
|
|
|
|
|
|
|
We have received your form, and |
439
|
|
|
|
|
|
|
we will get back to you shortly. |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
NOTE: It is not necessary that your HTML file be called 'thankyou.html'. You may name |
444
|
|
|
|
|
|
|
this file anything you like. The only naming limitation is that the name of this |
445
|
|
|
|
|
|
|
file should be correctly referenced in your 'mailform.cgi', in the variable 'SUCCESS_REDIRECT_URL'. |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=head2 Create 'mailform.cgi' |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
The file 'mailform.cgi' is where all the functionality of CGI::Application::Mailform |
453
|
|
|
|
|
|
|
is configured. This file is referred to as a "CGI instance script" because it |
454
|
|
|
|
|
|
|
creates an "instance" of your form. A single website may have as many instance |
455
|
|
|
|
|
|
|
scripts as needed. All of these instance scripts may use CGI::Application::Mailform. |
456
|
|
|
|
|
|
|
They may each use a different form (with different fields, etc.) if desired. |
457
|
|
|
|
|
|
|
The ability to create multiple instances of a single |
458
|
|
|
|
|
|
|
application, each with a different configuration is one of the benefits |
459
|
|
|
|
|
|
|
of building web-based applications using the CGI::Application framework. |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
Your instance script, 'mailform.cgi', must be created in such a way that it is |
462
|
|
|
|
|
|
|
treated by your web server as an executable CGI application (as opposed to a |
463
|
|
|
|
|
|
|
document). Generally (on UNIX), this entails setting the "execute bit" on the file and |
464
|
|
|
|
|
|
|
configuring your web server to treat files ending ".cgi" as CGI applications. |
465
|
|
|
|
|
|
|
Please refer to your particular web server's manual for configuration details. |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
Your instance script 'mailform.cgi' must start with the following: |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
#!/usr/bin/perl -w |
470
|
|
|
|
|
|
|
use CGI::Application::Mailform; |
471
|
|
|
|
|
|
|
my $mf = CGI::Application::Mailform->new(); |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
These lines invoke the Perl interpreter, include the CGI::Application::Mailform |
474
|
|
|
|
|
|
|
module, and instantiate a Mailform object, respectively. (The |
475
|
|
|
|
|
|
|
author assumes your Perl binary is located at "/usr/bin/perl". If it is not, |
476
|
|
|
|
|
|
|
change the first line to refer to the correct location of your Perl binary.) |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
Once you have a Mailform object ($mf), you have to configure the Mailform for your |
479
|
|
|
|
|
|
|
particular application. This is done by using the param() method to set a number of |
480
|
|
|
|
|
|
|
variables. These variables are specified as follows. |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
B |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
=over 4 |
488
|
|
|
|
|
|
|
|
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=item MAIL_FROM |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
$mf->param('MAIL_FROM' => 'webmaster@your.domain'); |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
This variable specifies the email address from which the email created by this |
495
|
|
|
|
|
|
|
mailform will appear to be sent. This can be any address you like. |
496
|
|
|
|
|
|
|
Typically, this will be "webmaster@your.domain". Keep in mind, this is |
497
|
|
|
|
|
|
|
the address to which a bounce or a reply will be sent if one is generated |
498
|
|
|
|
|
|
|
as a result of the mailform email. The MAIL_FROM can also be useful for |
499
|
|
|
|
|
|
|
assisting the recipient of these email messages in automatically filtering |
500
|
|
|
|
|
|
|
and organizing the submissions they receive. |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
This variable is required. If not specified, CGI::Application::Mailform |
503
|
|
|
|
|
|
|
will die() with appropriate errors. |
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=item MAIL_TO |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
$mf->param('MAIL_TO' => 'form_recipient@your.domain'); |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
This variable specifies the email address to which the email created by this |
511
|
|
|
|
|
|
|
mailform should be sent. This should be the email address of the person to |
512
|
|
|
|
|
|
|
whom the form contents should be emailed. This person will receive a |
513
|
|
|
|
|
|
|
reasonably formatted message every time this mailform is submitted. |
514
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
This variable is required. If not specified, CGI::Application::Mailform |
516
|
|
|
|
|
|
|
will die() with appropriate errors. |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=item HTMLFORM_REDIRECT_URL |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
$mf->param('HTMLFORM_REDIRECT_URL' => '/uri/or/url/to/mailform.html'); |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
This variable specifies the URL (or URI) to which the web user should be |
524
|
|
|
|
|
|
|
redirected before they have submitted the mailform. This should be the |
525
|
|
|
|
|
|
|
HTML form which the user fills out, the contents of which will be |
526
|
|
|
|
|
|
|
emailed once they are submitted. |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
This variable is required. If not specified, CGI::Application::Mailform |
529
|
|
|
|
|
|
|
will die() with appropriate errors. |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
=item SUCCESS_REDIRECT_URL |
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
$mf->param('SUCCESS_REDIRECT_URL' => '/uri/or/url/to/thankyou.html'); |
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
This variable specifies the URL (or URI) to which the web user should be |
537
|
|
|
|
|
|
|
redirected once they have submitted the mailform. Typically, this would be |
538
|
|
|
|
|
|
|
a "thank you" screen which assures the user that their form submission has |
539
|
|
|
|
|
|
|
been received and processed. |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
This variable is required. If not specified, CGI::Application::Mailform |
542
|
|
|
|
|
|
|
will die() with appropriate errors. |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
=item FORM_FIELDS |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
$mf->param('FORM_FIELDS' => [qw/name address comments etc/]); |
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
This variable specifies the list of HTML form fields which will be |
550
|
|
|
|
|
|
|
processed and sent via email to the specified recipient. Only the |
551
|
|
|
|
|
|
|
form fields specified in this list will be put in the email message |
552
|
|
|
|
|
|
|
which is generated by this mailform and sent to the specified |
553
|
|
|
|
|
|
|
recipient. |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
The value of this variable must be an array reference. |
556
|
|
|
|
|
|
|
This variable is required. If not specified, CGI::Application::Mailform |
557
|
|
|
|
|
|
|
will die() with appropriate errors. |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
=back |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
B |
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
=over 4 |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
=item SMTP_HOST |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
$mf->param('SMTP_HOST' => 'mail.your.domain'); |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
This variable specifies the Internet host name (or IP address) of the |
575
|
|
|
|
|
|
|
server which provides Simple Mail Transfer Protocol (SMTP) services. |
576
|
|
|
|
|
|
|
CGI::Application::Mailform sends all mail via SMTP using Net::SMTP. |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
If SMTP_HOST is unspecified, Net::SMTP will use the default host |
579
|
|
|
|
|
|
|
which was specified when Net::SMTP was installed. If |
580
|
|
|
|
|
|
|
CGI::Application::Mailform is unable to make an SMTP connection, |
581
|
|
|
|
|
|
|
or successfully send mail via the SMTP host, it will die() with |
582
|
|
|
|
|
|
|
appropriate errors. |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
=item SUBJECT |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
$mf->param('SUBJECT' => 'New form submission'); |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
This variable specifies the subject line of the email message which is |
590
|
|
|
|
|
|
|
created by this mailform. The subject is useful to the mailform recipient |
591
|
|
|
|
|
|
|
in easily recognizing (and possibly filtering) form submissions. |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
This variable is optional. If not supplied, CGI::Application::Mailform will |
594
|
|
|
|
|
|
|
set the subject to a reasonable default. |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=item ENV_FIELDS |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
$mf->param('ENV_FIELDS' => [qw/REMOTE_ADDR HTTP_USER_AGENT/]); |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
This variable specifies the list of "environment" variables which will be |
602
|
|
|
|
|
|
|
processed and sent via email to the specified recipient. Only the |
603
|
|
|
|
|
|
|
environment variables specified in this list will be put in the email message |
604
|
|
|
|
|
|
|
which is generated by this mailform and sent to the specified |
605
|
|
|
|
|
|
|
recipient. |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
Any environment variable which is present in the CGI |
608
|
|
|
|
|
|
|
environment may be included. Typical variables might be: |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
AUTH_TYPE |
611
|
|
|
|
|
|
|
CONTENT_LENGTH |
612
|
|
|
|
|
|
|
CONTENT_TYPE |
613
|
|
|
|
|
|
|
GATEWAY_INTERFACE |
614
|
|
|
|
|
|
|
HTTP_ACCEPT |
615
|
|
|
|
|
|
|
HTTP_USER_AGENT |
616
|
|
|
|
|
|
|
PATH_INFO |
617
|
|
|
|
|
|
|
PATH_TRANSLATED |
618
|
|
|
|
|
|
|
QUERY_STRING |
619
|
|
|
|
|
|
|
REMOTE_ADDR |
620
|
|
|
|
|
|
|
REMOTE_HOST |
621
|
|
|
|
|
|
|
REMOTE_IDENT |
622
|
|
|
|
|
|
|
REMOTE_USER |
623
|
|
|
|
|
|
|
REQUEST_METHOD |
624
|
|
|
|
|
|
|
SCRIPT_NAME |
625
|
|
|
|
|
|
|
SERVER_NAME |
626
|
|
|
|
|
|
|
SERVER_PORT |
627
|
|
|
|
|
|
|
SERVER_PROTOCOL |
628
|
|
|
|
|
|
|
SERVER_SOFTWARE |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
See your web server documentation for a complete list and descriptions |
631
|
|
|
|
|
|
|
of the available environment variables. The list of environment variables |
632
|
|
|
|
|
|
|
specified by the CGI protocol can be found at the following URL: |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
http://hoohoo.ncsa.uiuc.edu/cgi/env.html |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
The value of this variable must be an array reference. This variable |
637
|
|
|
|
|
|
|
is optional. If not specified, no environment variables will be included |
638
|
|
|
|
|
|
|
in the mailform email message. |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
=back |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
Finally, you must actually cause your Mailform to be executed by calling the run() |
644
|
|
|
|
|
|
|
method. Your instance script 'mailform.cgi' should end with the following lines: |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
$mf->run(); |
647
|
|
|
|
|
|
|
exit(0); |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
These lines cause your configured Mailform ($mf) to be executed, and for the program to |
650
|
|
|
|
|
|
|
cleanly exit, respectively. |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
NOTE: It is not necessary that your HTML file be called 'mailform.cgi'. You may name |
653
|
|
|
|
|
|
|
this file anything you like. The only naming limitations are that this file should be |
654
|
|
|
|
|
|
|
named so that your web server recognizes it as an executable CGI, and that your |
655
|
|
|
|
|
|
|
'mailform.html' file specifies your instance script in the "action" attribute of the |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
All things considered, your CGI instance script will be a very small, simple file. Unlike |
660
|
|
|
|
|
|
|
other reusable "mailform" scripts, the instance scripts are specifically intended to be |
661
|
|
|
|
|
|
|
very easy to work with. Essentially, these instance scripts are "configuration files" for |
662
|
|
|
|
|
|
|
your web-based application. The structure of instance scripts is a benefit of |
663
|
|
|
|
|
|
|
building applications based on the CGI::Application framework. |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
=head1 SEE ALSO |
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
L |
670
|
|
|
|
|
|
|
|
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
=head1 AUTHOR |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
Jesse Erlbaum |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
=head1 LICENSE |
678
|
|
|
|
|
|
|
|
679
|
|
|
|
|
|
|
Copyright (c) 2001, 2002, Jesse Erlbaum . |
680
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
This library is free software; you can redistribute it |
682
|
|
|
|
|
|
|
and/or modify it under the same terms as Perl itself. |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
=cut |
688
|
|
|
|
|
|
|
|
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
|
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
1; |
693
|
|
|
|
|
|
|
|