diff options
author | Matthew Somerville <matthew@mysociety.org> | 2011-06-03 13:43:36 +0100 |
---|---|---|
committer | Matthew Somerville <matthew@mysociety.org> | 2011-06-03 13:43:36 +0100 |
commit | 7b405637a1ac3436cf90acc7d5ad46f1b80c8250 (patch) | |
tree | 94759a8b2442e3acd54c464d73d4b3f8f6070eb0 | |
parent | a0740c6513a2bb21bfbeda02c5fe673a191f72af (diff) |
Fix broken contact form report handling, stop HTML injection, and remove old contact code.
-rw-r--r-- | conf/httpd.conf | 7 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Contact.pm | 23 | ||||
-rw-r--r-- | t/app/controller/contact.t | 34 | ||||
-rw-r--r-- | templates/web/default/contact/index.html | 32 | ||||
-rw-r--r-- | templates/web/default/contact/submit.html | 18 | ||||
-rw-r--r-- | templates/web/default/questionnaire/completed.html | 2 | ||||
-rw-r--r-- | templates/web/fiksgatami/contact/address.html | 0 | ||||
-rw-r--r-- | templates/website/contact | 42 | ||||
-rwxr-xr-x | web/contact.cgi | 245 |
9 files changed, 66 insertions, 337 deletions
diff --git a/conf/httpd.conf b/conf/httpd.conf index 1de0f6f4a..5bdb08fd8 100644 --- a/conf/httpd.conf +++ b/conf/httpd.conf @@ -86,10 +86,6 @@ RewriteRule ^/reports/{/rss/(.*)}$ /rss/$1 [R=permanent,L] # RewriteRule ^/report/([0-9]+) /report/$1 [R,L] RewriteRule ^/alerts/?$ /alert [R=permanent,L] -# JSON API for summaries of reports -# RewriteRule ^/json/problems/new$ /json.cgi?type=new_problems [QSA,L] -# RewriteRule ^/json/problems/fixed$ /json.cgi?type=fixed_problems [QSA,L] - # Proxy tilma so that our js code can make calls on the originating server. Use # a RewriteRule rather than ProxyPass so that Apache's processing order is more # predictable. ProxyPassReverse is not affected by this. @@ -105,10 +101,7 @@ RewriteRule /(.+) /$1 [L] # Explicitly capture all cgi files so that we can remove them one by one # RewriteRule ^/confirm(.*) /confirm.cgi$1 [L] -# RewriteRule ^/contact(.*) /contact.cgi$1 [L] RewriteRule ^/flickr(.*) /flickr.cgi$1 [L] -# RewriteRule ^/fun(.*) /fun.cgi$1 [L] -# RewriteRule ^/json(.*) /json.cgi$1 [L] # RewriteRule ^/questionnaire(.*) /questionnaire.cgi$1 [L] # RewriteRule ^/reports(.*) /reports.cgi$1 [L] # RewriteRule ^/rss(.*) /rss.cgi$1 [L] diff --git a/perllib/FixMyStreet/App/Controller/Contact.pm b/perllib/FixMyStreet/App/Controller/Contact.pm index 558a354c6..b179680d0 100644 --- a/perllib/FixMyStreet/App/Controller/Contact.pm +++ b/perllib/FixMyStreet/App/Controller/Contact.pm @@ -4,8 +4,6 @@ use namespace::autoclean; BEGIN { extends 'Catalyst::Controller'; } -use mySociety::Random qw(random_bytes); - =head1 NAME FixMyStreet::App::Controller::Contact - Catalyst Controller @@ -43,6 +41,7 @@ sub submit : Path('submit') : Args(0) { return unless $c->forward('setup_request') + && $c->forward('determine_contact_type') && $c->forward('validate') && $c->forward('prepare_params_for_email') && $c->forward('send_email'); @@ -69,7 +68,7 @@ sub determine_contact_type : Private { { 'select' => [ 'title', 'detail', 'name', - 'anonymous', + 'anonymous', 'id', 'user_id', 'confirmed', ] } @@ -85,7 +84,6 @@ sub determine_contact_type : Private { elsif ($problem) { $c->stash->{problem} = $problem; } - $c->stash->{id} = $id; } return 1; @@ -150,27 +148,26 @@ sub prepare_params_for_email : Private { $c->stash->{message} =~ s/\r\n/\n/g; $c->stash->{subject} =~ s/\r|\n/ /g; - my $base_url = $c->cobrand->base_url_for_emails; + my $base_url = $c->cobrand->base_url_for_emails( $c->cobrand->extra_data ); my $admin_base_url = $c->cobrand->admin_base_url || 'https://secure.mysociety.org/admin/bci/'; - if ( $c->stash->{problem} and $c->stash->{update} ) { + if ( $c->stash->{update} ) { - # FIXME - correct url here - my $problem_url = $base_url; - my $admin_url = $admin_base_url; + my $problem_url = $base_url . '/report/' . $c->stash->{update}->problem_id + . '#update_' . $c->stash->{update}->id; + my $admin_url = $admin_base_url . '?page=update_edit;id=' . $c->stash->{update}->id; $c->stash->{message} .= sprintf( " \n\n[ Complaint about update %d on report %d - %s - %s ]", $c->stash->{update}->id, - $c->stash->{problem}->id, + $c->stash->{update}->problem_id, $problem_url, $admin_url ); } elsif ( $c->stash->{problem} ) { - # FIXME - correct url here - my $problem_url = $base_url; - my $admin_url = $admin_base_url; + my $problem_url = $base_url . '/report/' . $c->stash->{problem}->id; + my $admin_url = $admin_base_url . '?page=report_edit;id=' . $c->stash->{problem}->id; $c->stash->{message} .= sprintf( " \n\n[ Complaint about report %d - %s - %s ]", $c->stash->{problem}->id, diff --git a/t/app/controller/contact.t b/t/app/controller/contact.t index 73660306d..9808ef762 100644 --- a/t/app/controller/contact.t +++ b/t/app/controller/contact.t @@ -10,6 +10,8 @@ $mech->get_ok('/contact'); $mech->title_like(qr/Contact Us/); $mech->content_contains("We'd love to hear what you think about this site"); +my $problem_main; + for my $test ( { name => 'A User', @@ -20,6 +22,7 @@ for my $test ( confirmed => '2011-05-04 10:44:28.145168', anonymous => 0, meta => 'Reported by A User at 10:44, Wednesday 4 May 2011', + main => 1, }, { name => 'A User', @@ -111,7 +114,11 @@ for my $test ( } $update->delete if $update; - $problem->delete; + if ($test->{main}) { + $problem_main = $problem; + } else { + $problem->delete; + } }; } @@ -193,7 +200,7 @@ for my $test ( field_errors => [ 'Please write a message', ] }, { - url => '/contact?id=1', + url => '/contact?id=' . $problem_main->id, fields => { em => 'test@example.com', name => 'A name', @@ -228,12 +235,25 @@ for my $test ( message => 'A message', }, }, + { + fields => { + em => 'test@example.com', + name => 'A name', + subject => 'A subject', + message => 'A message', + id => $problem_main->id, + }, + }, ) { subtest 'check email sent correctly' => sub { $mech->clear_emails_ok; - $mech->get_ok('/contact'); + if ($test->{fields}{id}) { + $mech->get_ok('/contact?id=' . $test->{fields}{id}); + } else { + $mech->get_ok('/contact'); + } $mech->submit_form_ok( { with_fields => $test->{fields} } ); $mech->content_contains('Thanks for your feedback'); $mech->email_count_is(1); @@ -243,7 +263,13 @@ for my $test ( is $email->header('Subject'), 'FMS message: ' . $test->{fields}->{subject}, 'subject'; is $email->header('From'), "\"$test->{fields}->{name}\" <$test->{fields}->{em}>", 'from'; like $email->body, qr/$test->{fields}->{message}/, 'body'; - like $email->body, qr/Sent by contact.cgi on \S+. IP address (?:\d{1,3}\.){3,}\d{1,3}/, 'body footer' + like $email->body, qr/Sent by contact.cgi on \S+. IP address (?:\d{1,3}\.){3,}\d{1,3}/, 'body footer'; + my $problem_id = $test->{fields}{id}; + like $email->body, qr/Complaint about report $problem_id/, 'reporting a report' + if $test->{fields}{id}; }; } + +$problem_main->delete; + done_testing(); diff --git a/templates/web/default/contact/index.html b/templates/web/default/contact/index.html index 8fd280ab8..dc64dd554 100644 --- a/templates/web/default/contact/index.html +++ b/templates/web/default/contact/index.html @@ -1,20 +1,20 @@ -[% INCLUDE 'header.html', title => loc('Contact Us') %] +[% INCLUDE 'header.html', + title = loc('Contact Us') + robots = 'noindex,nofollow' +%] <h1>[% loc('Contact the team') %]</h1> <form method="post" action="/contact/submit"> -<input type="hidden" name="submit_form" value="1"> - - [% INCLUDE 'errors.html' %] [% IF update %] + <p> [% loc('You are reporting the following update for being abusive, containing personal information, or similar:') %] </p> - [% IF update.text %] <blockquote> <p> [% IF update.anonymous %] @@ -29,15 +29,14 @@ </p> </blockquote> - [% END %] <input type="hidden" name="update_id" value="[% update.id %]"> - <input type="hidden" name="id" value="[% problem.id %]"> + <input type="hidden" name="id" value="[% update.problem_id %]"> + [% ELSIF problem %] <p> [% loc('You are reporting the following problem report for being abusive, containing personal information, or similar:') %] </p> - [% IF problem.title %] <blockquote> <h2>[% problem.title | html %]</h2> @@ -55,13 +54,10 @@ </blockquote> <input type="hidden" name="id" value="[% problem.id %]"> - [% END %] + [% ELSE %] -[% IF id %] -<input type="hidden" name="id" value="[% id %]"> -[% END %] -[% INCLUDE 'contact/blurb.html' %] + [% INCLUDE 'contact/blurb.html' %] [% END %] @@ -70,7 +66,7 @@ [% END %] <div class="form-field"> <label for="form_name">[% loc('Your name:') %]</label> -<input type="text" name="name" id="form_name" value="[% form_name %]" size="30"></div> +<input type="text" name="name" id="form_name" value="[% form_name | html %]" size="30"></div> [% IF field_errors.em %] @@ -78,14 +74,14 @@ [% END %] <div class="form-field"> <label for="form_email">[% loc('Your email:') %]</label> -<input type="text" name="em" id="form_email" value="[% em %]" size="30"></div> +<input type="text" name="em" id="form_email" value="[% em | html %]" size="30"></div> [% IF field_errors.subject %] <div class="form-error">[% field_errors.subject %]</div> [% END %] <div class="form-field"> <label for="form_subject">[% loc('Subject:') %]</label> -<input type="text" name="subject" id="form_subject" value="[% subject %]" size="30"></div> +<input type="text" name="subject" id="form_subject" value="[% subject | html %]" size="30"></div> [% IF field_errors.message %] <div class="form-error">[% field_errors.message %]</div> @@ -93,9 +89,11 @@ <div class="form-field"> <label for="form_message">[% loc('Message:') %]</label> -<textarea name="message" id="form_message" rows="7" cols="50">[% message %]</textarea></div> +<textarea name="message" id="form_message" rows="7" cols="50">[% message | html %]</textarea></div> <div class="checkbox"><input type="submit" value="[% loc('Post') %]"></div> +[% c.cobrand.form_elements('contactForm') %] + </form> [% INCLUDE 'contact/address.html' %] diff --git a/templates/web/default/contact/submit.html b/templates/web/default/contact/submit.html index 12f3f30a6..3845e9210 100644 --- a/templates/web/default/contact/submit.html +++ b/templates/web/default/contact/submit.html @@ -1,18 +1,20 @@ -[% INCLUDE 'header.html', title => loc('Contact Us') %] +[% INCLUDE 'header.html', title = loc('Contact Us') %] <h1>[% loc('Contact the team') %]</h1> -<form method="post" action="/contact/submit"> - -<input type="hidden" name="submit_form" value="1"> - - -<p> [% IF success %] + + <p> [% loc("Thanks for your feedback. We'll get back to you as soon as we can!") %] + </p> + [% display_crosssell_advert( em, form_name, 'emailunvalidated', 1 ) %] + [% ELSE %] + + <p> [% tprintf( loc('Failed to send message. Please try again, or <a href="mailto:%s">email us</a>.'), contact_email ) %] + </p> + [% END %] -</p> [% INCLUDE 'footer.html' %] diff --git a/templates/web/default/questionnaire/completed.html b/templates/web/default/questionnaire/completed.html index afac7aa29..4a6419ccb 100644 --- a/templates/web/default/questionnaire/completed.html +++ b/templates/web/default/questionnaire/completed.html @@ -23,6 +23,6 @@ why not <a href="http://www.pledgebank.com/new">make and publicise a pledge</a>? [% END %] [% IF advert_outcome %] - [% display_crosssell_advert( problem.user.email, problem.name, council, problem.council ) %] + [% display_crosssell_advert( problem.user.email, problem.name, 'council', problem.council ) %] [% END %] diff --git a/templates/web/fiksgatami/contact/address.html b/templates/web/fiksgatami/contact/address.html new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/templates/web/fiksgatami/contact/address.html diff --git a/templates/website/contact b/templates/website/contact deleted file mode 100644 index b1103d3f1..000000000 --- a/templates/website/contact +++ /dev/null @@ -1,42 +0,0 @@ -<h1>{{ $header }}</h1> -{{ $errors }} -<form method="post" action="{{ $form_action }}"> -<input type="hidden" name="submit_form" value="1"> - -{{ $intro }} -{{ if ( $item_title ) { - "<blockquote><h2>$item_title</h2><p>$item_meta</p><p>$item_body</p></blockquote>"; - -} }} - -{{ $hidden_vals }} -{{ if ( $field_errors{name}) { - "<div class='form-error'>$field_errors{name}</div>"; -} }} -<div class="form-field"> -<label for="form_name">{{ $label_name }}</label> -<input type="text" name="name" id="form_name" value="{{ $input_h{name} }}" size="30"></div> - -{{ if ( $field_errors{email}) { - "<div class='form-error'>$field_errors{email}</div>"; -} }} -<div class="form-field"> -<label for="form_email">{{ $label_email }}</label> -<input type="text" name="em" id="form_email" value="{{ $input_h{em} }}" size="30"></div> -{{ if ( $field_errors{subject}) { - "<div class='form-error'>$field_errors{subject}</div>"; -} }} -<div class="form-field"> -<label for="form_subject">{{ $label_subject }}</label> -<input type="text" name="subject" id="form_subject" value="{{ $input_h{subject} }}" size="30"></div> -{{ if ( $field_errors{message}) { - "<div class='form-error'>$field_errors{message}</div>"; -} }} -<div class="form-field"> -<label for="form_message">{{ $label_message }}</label> -<textarea name="message" id="form_message" rows="7" cols="50">{{ $input_h{message} }}</textarea></div> -<div class="checkbox"><input type="submit" value="{{ $label_submit }}"></div> -{{ $cobrand_form_elements }} -</form> - -{{ $contact_details }} diff --git a/web/contact.cgi b/web/contact.cgi deleted file mode 100755 index b3af1688b..000000000 --- a/web/contact.cgi +++ /dev/null @@ -1,245 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# contact.cgi: -# Contact page for FixMyStreet -# -# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: contact.cgi,v 1.58 2009-12-17 14:57:34 louise Exp $ - -use strict; -use Standard; -use CrossSell; -use mySociety::Email; -use mySociety::EmailUtil; -use mySociety::Web qw(ent); -use mySociety::Random qw(random_bytes); - -# Main code for index.cgi -sub main { - my $q = shift; - print Page::header($q, title=>_('Contact Us'), context=>'contact', robots => 'noindex,nofollow'); - my $out = ''; - if ($q->param('submit_form')) { - $out = contact_submit($q); - } else { - $out = contact_page($q, [], {}); - } - print $out; - print Page::footer($q); -} -Page::do_fastcgi(\&main); - -sub contact_submit { - my $q = shift; - my @vars = qw(name em subject message id update_id); - my %input = map { $_ => $q->param($_) || '' } @vars; - my $cobrand = Page::get_cobrand($q); - my @errors; - my %field_errors; - $field_errors{name} = _('Please give your name') unless $input{name} =~ /\S/; - if ($input{em} !~ /\S/) { - $field_errors{email} = _('Please give your email'); - } elsif (!mySociety::EmailUtil::is_valid_email($input{em})) { - $field_errors{email} = _('Please give a valid email address'); - } - $field_errors{subject} = _('Please give a subject') unless $input{subject} =~ /\S/; - $field_errors{message} = _('Please write a message') unless $input{message} =~ /\S/; - push(@errors, _('Illegal ID')) if (($input{id} && $input{id} !~ /^[1-9]\d*$/) || ($input{update_id} && $input{update_id} !~ /^[1-9]\d*$/)); - return contact_page($q, \@errors, \%field_errors) if (@errors || scalar keys %field_errors); - - (my $message = $input{message}) =~ s/\r\n/\n/g; - (my $subject = $input{subject}) =~ s/\r|\n/ /g; - my $extra_data = Cobrand::extra_data($cobrand, $q); - my $base_url = Cobrand::base_url_for_emails($cobrand, $extra_data); - my $admin_base_url = Cobrand::admin_base_url($cobrand); - if (!$admin_base_url) { - $admin_base_url = "https://secure.mysociety.org/admin/bci/"; - } - if ($input{id} && $input{update_id}) { - $message .= "\n\n[ Complaint about update $input{update_id} on report $input{id} - " - . $base_url . "/report/$input{id}#update_$input{update_id} - " - . "$admin_base_url?page=update_edit;id=$input{update_id} ]"; - } elsif ($input{id}) { - $message .= "\n\n[ Complaint about report $input{id} - " - . $base_url . "/report/$input{id} - " - . "$admin_base_url?page=report_edit;id=$input{id} ]"; - } - my $postfix = '[ Sent by contact.cgi on ' . - $ENV{'HTTP_HOST'} . '. ' . - "IP address " . $ENV{'REMOTE_ADDR'} . - ($ENV{'HTTP_X_FORWARDED_FOR'} ? ' (forwarded from '.$ENV{'HTTP_X_FORWARDED_FOR'}.')' : '') . '. ' . - ' ]'; - - my $recipient = Cobrand::contact_email($cobrand); - my $recipient_name = Cobrand::contact_name($cobrand); - my $email = mySociety::Email::construct_email({ - _body_ => "$message\n\n$postfix", - From => [$input{em}, $input{name}], - To => [[$recipient, _($recipient_name)]], - Subject => 'FMS message: ' . $subject, - 'Message-ID' => sprintf('<contact-%s-%s@mysociety.org>', time(), unpack('h*', random_bytes(5, 1))), - }); - my $result = mySociety::EmailUtil::send_email($email, $input{em}, $recipient); - if ($result == mySociety::EmailUtil::EMAIL_SUCCESS) { - my $message = _("Thanks for your feedback. We'll get back to you as soon as we can!"); - my $out = $q->p($message); - my $display_advert = Cobrand::allow_crosssell_adverts($cobrand); - my $advert = ''; - if ($display_advert) { - $advert = CrossSell::display_advert($q, $input{em}, $input{name}, emailunvalidated=>1 ); - $out .= $advert; - } - my %vars = (message => $message, - advert => $advert); - my $template_out = Page::template_include('confirmed-alert', $q, Page::template_root($q), %vars); - return $template_out if $template_out; - return $out; - } else { - return $q->p('Failed to send message. Please try again, or <a href="mailto:' . $recipient . '">email us</a>.'); - } -} - -sub contact_details { - my ($q) = @_; - my $out = ''; - my $sitename = _('FixMyStreet'); - my $contact_info = ''; - if ( mySociety::Config::get('COUNTRY') eq 'GB' ) { - # XXX Rewrite to make brandable? - $contact_info .= <<EOF; -<div class="contact-details"> -<p>$sitename is a service provided by mySociety, which is the project of a -registered charity. The charity is called UK Citizens Online Democracy and is charity number 1076346.</p> -<p>mySociety can be contacted by email at <a href="mailto:hello@mysociety.org">hello@mysociety.org</a>, -or by post at:</p> -<p>mySociety<br> -483 Green Lanes<br> -London<br> -N13 4BS<br> -UK</p> -</div> -EOF - $out .= $contact_info unless $q->{site} eq 'emptyhomes'; - } - return $out; -} - -sub generic_contact_text { - my ($q) = @_; - my $intro; - - if ($q->{site} eq 'emptyhomes') { - $intro .= $q->p(_('We’d love to hear what you think about this -website. Just fill in the form. Please don’t contact us about individual empty -homes; use the box accessed from <a href="/">the front page</a>.')); - } else { - my $cobrand = Page::get_cobrand($q); - my $mailto = Cobrand::contact_email($cobrand); - $mailto =~ s/\@/@/; - $intro .= $q->p(_('Please do <strong>not</strong> report problems through this form; messages go to -the team behind FixMyStreet, not a council. To report a problem, -please <a href="/">go to the front page</a> and follow the instructions.')); - $intro .= $q->p(sprintf(_("We'd love to hear what you think about this site. Just fill in the form, or send an email to <a href='mailto:%s'>%s</a>:"), $mailto, $mailto)); - } - return $intro; -} - -sub contact_page { - my ($q, $errors, $field_errors) = @_; - my @errors = @$errors; - my %field_errors = %{$field_errors}; - push @errors, _('There were problems with your report. Please see below.') if (scalar keys %field_errors); - my @vars = qw(name em subject message); - my %input = map { $_ => $q->param($_) || '' } @vars; - my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; - my $out = ''; - my $header = _('Contact the team'); - $errors = ''; - - if (@errors) { - $errors = '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>'; - } - my $cobrand = Page::get_cobrand($q); - my $form_action = Cobrand::url($cobrand, '/contact', $q); - - my $intro = ''; - my $item_title = ''; - my $item_body = ''; - my $item_meta = ''; - my $hidden_vals = ''; - my $id = $q->param('id'); - my $update_id = $q->param('update_id'); - $id = undef unless $id && $id =~ /^[1-9]\d*$/; - $update_id = undef unless $update_id && $update_id =~ /^[1-9]\d*$/; - if ($id) { - mySociety::DBHandle::configure( - Name => mySociety::Config::get('BCI_DB_NAME'), - User => mySociety::Config::get('BCI_DB_USER'), - Password => mySociety::Config::get('BCI_DB_PASS'), - Host => mySociety::Config::get('BCI_DB_HOST', undef), - Port => mySociety::Config::get('BCI_DB_PORT', undef) - ); - my $p = dbh()->selectrow_hashref( - 'select title,detail,name,anonymous,extract(epoch from confirmed) as confirmed - from problem where id=?', {}, $id); - if ($update_id) { - my $u = dbh()->selectrow_hashref( - 'select comment.text, comment.name, problem.title, extract(epoch from comment.confirmed) as confirmed - from comment, problem where comment.id=? - and comment.problem_id = problem.id - and comment.problem_id=?', {}, $update_id ,$id); - if (! $u) { - $intro = generic_contact_text($q); - } else { - $intro .= $q->p(_('You are reporting the following update for being abusive, containing personal information, or similar:')); - $item_title = ent($u->{title}); - $item_meta = $q->em( 'Update below added ', (!$u->{name}) ? 'anonymously' : "by " . ent($u->{name}), - ' at ' . Page::prettify_epoch($q, $u->{confirmed})); - $item_body = ent($u->{text}); - $hidden_vals .= '<input type="hidden" name="update_id" value="' . $update_id . '">'; - } - } else { - if (! $p) { - $intro = generic_contact_text($q); - } else { - $intro .= $q->p(_('You are reporting the following problem report for being abusive, containing personal information, or similar:')); - $item_title = ent($p->{title}); - my $date_time = Page::prettify_epoch($q, $p->{confirmed}); - $item_meta = $q->em( - $p->{anonymous} - ? sprintf(_('Reported anonymously at %s'), $date_time) - : sprintf(_('Reported by %s at %s'), ent($p->{name}), $date_time) - ); - $item_body = ent($p->{detail}); - } - } - $hidden_vals .= '<input type="hidden" name="id" value="' . $id . '">'; - } else { - $intro = generic_contact_text($q); - } - my $cobrand_form_elements = Cobrand::form_elements(Page::get_cobrand($q), 'contactForm', $q); - my %vars = ( - header => $header, - errors => $errors, - intro => $intro, - item_title => $item_title, - item_meta => $item_meta, - item_body => $item_body, - hidden_vals => $hidden_vals, - form_action => $form_action, - input_h => \%input_h, - field_errors => \%field_errors, - label_name => _('Your name:'), - label_email => _('Your email:'), - label_subject => _('Subject:'), - label_message => _('Message:'), - label_submit => _('Post'), - contact_details => contact_details($q), - cobrand_form_elements => $cobrand_form_elements - ); - $out .= Page::template_include('contact', $q, Page::template_root($q), %vars); - return $out; -} - |