aboutsummaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/css.css2
-rwxr-xr-xweb/index.cgi261
-rw-r--r--web/js.js15
-rwxr-xr-xweb/questionnaire.cgi228
4 files changed, 295 insertions, 211 deletions
diff --git a/web/css.css b/web/css.css
index 3318ae679..e2bbe2070 100644
--- a/web/css.css
+++ b/web/css.css
@@ -200,7 +200,7 @@ fieldset div.checkbox label, label.n {
width: 510px;
}
-#map_box p {
+p#copyright {
float: right;
margin: 0 0 1em 0;
font-size: 78%;
diff --git a/web/index.cgi b/web/index.cgi
index 87c9cb8a8..bed7cfae7 100755
--- a/web/index.cgi
+++ b/web/index.cgi
@@ -6,10 +6,7 @@
# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved.
# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
#
-# $Id: index.cgi,v 1.122 2007-05-04 00:19:59 matthew Exp $
-
-# TODO
-# Nothing is done about the update checkboxes - not stored anywhere on anything!
+# $Id: index.cgi,v 1.123 2007-05-04 14:36:56 matthew Exp $
use strict;
require 5.8.0;
@@ -296,24 +293,24 @@ sub display_form {
if ($input{skipped}) {
# Map is being skipped
if ($input{x} && $input{y}) {
- $easting = tile_to_os($input{x});
- $northing = tile_to_os($input{y});
+ $easting = Page::tile_to_os($input{x});
+ $northing = Page::tile_to_os($input{y});
} else {
my ($x, $y, $e, $n, $i, $error) = geocode($input{pc});
$easting = $e; $northing = $n; $island = $i;
}
} elsif ($pin_x && $pin_y) {
# Map was clicked on
- $pin_x = click_to_tile($pin_tile_x, $pin_x);
- $pin_y = click_to_tile($pin_tile_y, $pin_y, 1);
- $px = tile_to_px($pin_x, $input{x});
- $py = tile_to_px($pin_y, $input{y});
- $easting = tile_to_os($pin_x);
- $northing = tile_to_os($pin_y);
+ $pin_x = Page::click_to_tile($pin_tile_x, $pin_x);
+ $pin_y = Page::click_to_tile($pin_tile_y, $pin_y, 1);
+ $px = Page::tile_to_px($pin_x, $input{x});
+ $py = Page::tile_to_px($pin_y, $input{y});
+ $easting = Page::tile_to_os($pin_x);
+ $northing = Page::tile_to_os($pin_y);
} else {
# Normal form submission
- $px = os_to_px($input{easting}, $input{x});
- $py = os_to_px($input{northing}, $input{y});
+ $px = Page::os_to_px($input{easting}, $input{x});
+ $py = Page::os_to_px($input{northing}, $input{y});
$easting = $input_h{easting};
$northing = $input_h{northing};
}
@@ -360,15 +357,9 @@ sub display_form {
<h1>Reporting a problem</h1>
EOF
} else {
- my $pins = display_pin($q, $px, $py, 'purple');
- $out .= display_map($q, $input{x}, $input{y}, 2, 1, $pins);
- if ($px && $py) {
- $out .= <<EOF;
-<script type="text/javascript">
-drag_x = $px - 254; drag_y = 254 - $py;
-</script>
-EOF
- }
+ my $pins = Page::display_pin($q, $px, $py, 'purple');
+ $out .= Page::display_map($q, x => $input{x}, y => $input{y}, type => 2,
+ pins => $pins, px => $px, py => $py );
$out .= '<h1>Reporting a problem</h1>';
$out .= '<p>You have located the problem at the point marked with a purple pin on the map.
If this is not the correct location, simply click on the map again.</p>';
@@ -454,7 +445,7 @@ $category
<p align="right"><a href="$back">Back to listings</a></p>
EOF
- $out .= display_map_end(1);
+ $out .= Page::display_map_end(1);
return $out;
}
@@ -480,7 +471,7 @@ sub display_location {
return front_page($q, $error) if ($error);
my ($pins, $current_map, $current, $fixed) = map_pins($q, $x, $y);
- my $out = display_map($q, $x, $y, 1, 1, $pins);
+ my $out = Page::display_map($q, x => $x, y => $y, type => 1, pins => $pins );
$out .= '<h1>Click on the map to report a problem</h1>';
if (@errors) {
$out .= '<ul id="error"><li>' . join('</li><li>', @errors) . '</li></ul>';
@@ -535,7 +526,7 @@ EOF
$out .= '<li>No problems have been fixed yet</li>';
}
$out .= '</ol></div>';
- $out .= display_map_end(1);
+ $out .= Page::display_map_end(1);
return $out;
}
@@ -549,58 +540,26 @@ sub display_problem {
$input{y} ||= 0; $input{y} += 0;
# Get all information from database
- my $problem = dbh()->selectrow_arrayref(
- "select state, easting, northing, title, detail, name, extract(epoch from confirmed), photo, anonymous,
- extract(epoch from whensent-confirmed), council
+ my $problem = dbh()->selectrow_hashref(
+ "select state, easting, northing, title, detail, name, extract(epoch from confirmed) as time, photo, anonymous,
+ extract(epoch from whensent-confirmed) as whensent, council, id
from problem where id=? and state in ('confirmed','fixed', 'hidden')", {}, $input{id});
return display_location($q, 'Unknown problem ID') unless $problem;
- my ($state, $easting, $northing, $title, $desc, $name, $time,
- $photo, $anonymous, $whensent, $council) = @$problem;
- return front_page($q, 'That problem has been removed') if $state eq 'hidden';
- my $x = os_to_tile($easting);
- my $y = os_to_tile($northing);
+ return front_page($q, 'That problem has been removed') if $problem->{state} eq 'hidden';
+ my $x = Page::os_to_tile($problem->{easting});
+ my $y = Page::os_to_tile($problem->{northing});
my $x_tile = $input{x} || int($x);
my $y_tile = $input{y} || int($y);
+ my $px = Page::os_to_px($problem->{easting}, $x_tile);
+ my $py = Page::os_to_px($problem->{northing}, $y_tile);
- my $px = os_to_px($easting, $x_tile);
- my $py = os_to_px($northing, $y_tile);
-
- my $pins = display_pin($q, $px, $py, 'blue');
- my $out = display_map($q, $x_tile, $y_tile, 0, 1, $pins);
-
- $out .= "<h1>$title</h1>";
- $out .= <<EOF;
-<script type="text/javascript">
-drag_x = $px - 254; drag_y = 254 - $py;
-</script>
-EOF
-
- # Display information about problem
- $out .= '<p><em>Reported ';
- $out .= ($anonymous) ? 'anonymously' : "by " . ent($name);
- $out .= ' at ' . Page::prettify_epoch($time);
- if ($council) {
- if ($whensent) {
- $council =~ s/\|.*//g;
- my @councils = split /,/, $council;
- my $areas_info = mySociety::MaPit::get_voting_areas_info(\@councils);
- $council = join(' and ', map { $areas_info->{$_}->{name} } @councils);
- $out .= $q->br() . $q->small('Sent to ' . $council . ' ' .
- Page::prettify_duration($whensent) . ' later');
- }
- } else {
- $out .= $q->br() . $q->small('Not reported to council');
- }
- $out .= '</em></p> <p>';
- $out .= ent($desc);
- $out .= '</p>';
-
- if ($photo) {
- $out .= '<p align="center"><img src="/photo?id=' . $input{id} . '"></p>';
- }
+ my $pins = Page::display_pin($q, $px, $py, 'blue');
+ my $out = Page::display_map($q, x => $x_tile, y => $y_tile, type => 0,
+ pins => $pins, px => $px, py => $py );
+ $out .= Page::display_problem_text($q, $problem);
$out .= $q->p({align=>'right'},
- $q->a({href => '/contact?id=' . $input{id}}, $q->small('Offensive? Unsuitable? Tell us'))
+ $q->small($q->a({href => '/contact?id=' . $input{id}}, 'Offensive? Unsuitable? Tell us'))
);
my $back = NewURL($q, id=>undef, x=>$x_tile, y=>$y_tile);
$out .= '<p style="padding-bottom: 0.5em; border-bottom: dotted 1px #999999;" align="right"><a href="' . $back . '">Back to listings</a></p>';
@@ -647,7 +606,7 @@ EOF
}
my $fixed = ($input{fixed}) ? ' checked' : '';
- my $fixedline = $state eq 'fixed' ? '' : qq{
+ my $fixedline = $problem->{state} eq 'fixed' ? '' : qq{
<div class="checkbox"><input type="checkbox" name="fixed" id="form_fixed" value="1"$fixed>
<label for="form_fixed">This problem has been fixed</label></div>
};
@@ -667,7 +626,7 @@ $fixedline
</fieldset>
</form>
EOF
- $out .= display_map_end(0);
+ $out .= Page::display_map_end(0);
return $out;
}
@@ -675,12 +634,12 @@ sub map_pins {
my ($q, $x, $y) = @_;
my $pins = '';
- my $min_e = tile_to_os($x);
- my $min_n = tile_to_os($y);
- my $mid_e = tile_to_os($x+1);
- my $mid_n = tile_to_os($y+1);
- my $max_e = tile_to_os($x+2);
- my $max_n = tile_to_os($y+2);
+ my $min_e = Page::tile_to_os($x);
+ my $min_n = Page::tile_to_os($y);
+ my $mid_e = Page::tile_to_os($x+1);
+ my $mid_n = Page::tile_to_os($y+1);
+ my $max_e = Page::tile_to_os($x+2);
+ my $max_n = Page::tile_to_os($y+2);
my $current_map = select_all(
"select id,title,easting,northing from problem where state='confirmed'
@@ -691,9 +650,9 @@ sub map_pins {
my $count_fixed = 1;
foreach (@$current_map) {
push(@ids, $_->{id});
- my $px = os_to_px($_->{easting}, $x);
- my $py = os_to_px($_->{northing}, $y);
- $pins .= display_pin($q, $px, $py, 'red', $count_prob++);
+ my $px = Page::os_to_px($_->{easting}, $x);
+ my $py = Page::os_to_px($_->{northing}, $y);
+ $pins .= Page::display_pin($q, $px, $py, 'red', $count_prob++);
}
my $current = [];
@@ -706,9 +665,9 @@ sub map_pins {
and state = 'confirmed'" . (@ids ? ' and id not in (' . join(',' , @ids) . ')' : '') . "
order by distance, created desc limit $limit", $mid_e, $mid_n);
foreach (@$current) {
- my $px = os_to_px($_->{easting}, $x);
- my $py = os_to_px($_->{northing}, $y);
- $pins .= display_pin($q, $px, $py, 'red', $count_prob++);
+ my $px = Page::os_to_px($_->{easting}, $x);
+ my $py = Page::os_to_px($_->{northing}, $y);
+ $pins .= Page::display_pin($q, $px, $py, 'red', $count_prob++);
}
}
my $fixed = select_all(
@@ -717,97 +676,13 @@ sub map_pins {
where nearby.problem_id = problem.id and state='fixed'
order by created desc limit 9", $mid_e, $mid_n);
foreach (@$fixed) {
- my $px = os_to_px($_->{easting}, $x);
- my $py = os_to_px($_->{northing}, $y);
- $pins .= display_pin($q, $px, $py, 'green', $count_fixed++);
+ my $px = Page::os_to_px($_->{easting}, $x);
+ my $py = Page::os_to_px($_->{northing}, $y);
+ $pins .= Page::display_pin($q, $px, $py, 'green', $count_fixed++);
}
return ($pins, $current_map, $current, $fixed);
}
-sub display_pin {
- my ($q, $px, $py, $col, $num) = @_;
- $num = '' unless $num;
- my %cols = (red=>'R', green=>'G', blue=>'B', purple=>'P');
- my $out = '<img class="pin" src="/i/pin' . $cols{$col}
- . $num . '.gif" alt="Problem" style="top:' . ($py-59)
- . 'px; right:' . ($px-31) . 'px; position: absolute;">';
- return $out unless $_ && $_->{id} && $col ne 'blue';
- my $url = NewURL($q, id=>$_->{id}, x=>undef, y=>undef);
- $out = '<a title="' . $_->{title} . '" href="' . $url . '">' . $out . '</a>';
- return $out;
-}
-
-# display_map Q X Y TYPE COMPASS PINS
-# X,Y is bottom left tile of 2x2 grid
-# TYPE is 1 if the map is clickable, 0 if not
-# COMPASS is 1 to show the compass, 0 to not
-# PINS is HTML of pins to show
-sub display_map {
- my ($q, $x, $y, $type, $compass, $pins) = @_;
- $pins ||= '';
- $x = 0 if ($x<=0);
- $y = 0 if ($y<=0);
- my $url = mySociety::Config::get('TILES_URL');
- my $tiles_url = $url . $x . '-' . ($x+1) . ',' . $y . '-' . ($y+1) . '/RABX';
- my $tiles = LWP::Simple::get($tiles_url);
- throw Error::Simple("Unable to get tiles from URL $tiles_url\n") if !$tiles;
- my $tileids = RABX::unserialise($tiles);
- my $tl = $x . '.' . ($y+1);
- my $tr = ($x+1) . '.' . ($y+1);
- my $bl = $x . '.' . $y;
- my $br = ($x+1) . '.' . $y;
- return '<div id="side">' if (!$tileids->[0][0] || !$tileids->[0][1] || !$tileids->[1][0] || !$tileids->[1][1]);
- my $tl_src = $url . $tileids->[0][0];
- my $tr_src = $url . $tileids->[0][1];
- my $bl_src = $url . $tileids->[1][0];
- my $br_src = $url . $tileids->[1][1];
-
- my $out = '';
- my $img_type;
- if ($type) {
- my $encoding = '';
- $encoding = ' enctype="multipart/form-data"' if ($type==2);
- my $pc = $q->param('pc') || '';
- my $pc_enc = ent($pc);
- $out .= <<EOF;
-<form action="./" method="post" id="mapForm"$encoding>
-<input type="hidden" name="submit_map" value="1">
-<input type="hidden" name="x" value="$x">
-<input type="hidden" name="y" value="$y">
-<input type="hidden" name="pc" value="$pc_enc">
-EOF
- $img_type = '<input type="image"';
- } else {
- $img_type = '<img';
- }
- my $imgw = '254px';
- my $imgh = '254px';
- $out .= <<EOF;
-<script type="text/javascript">
-var x = $x - 2; var y = $y - 2;
-var drag_x = 0; var drag_y = 0;
-</script>
-<div id="map_box">
- <div id="map"><div id="drag">
- $img_type alt="NW map tile" id="t2.2" name="tile_$tl" src="$tl_src" style="top:0px; left:0px;">$img_type alt="NE map tile" id="t2.3" name="tile_$tr" src="$tr_src" style="top:0px; left:$imgw;"><br>$img_type alt="SW map tile" id="t3.2" name="tile_$bl" src="$bl_src" style="top:$imgh; left:0px;">$img_type alt="SE map tile" id="t3.3" name="tile_$br" src="$br_src" style="top:$imgh; left:$imgw;">
- $pins
- </div></div>
- <p>&copy; Crown copyright. All rights reserved.
- Department for Constitutional Affairs 100037819&nbsp;2007</p>
- </div>
-EOF
- $out .= Page::compass($q, $x, $y) if $compass;
- $out .= '<div id="side">';
- return $out;
-}
-
-sub display_map_end {
- my ($type) = @_;
- my $out = '</div>';
- $out .= '</form>' if ($type);
- return $out;
-}
-
sub geocode_choice {
my $choices = shift;
my $out = '<p>We found more than one match for that location:</p> <ul>';
@@ -833,8 +708,8 @@ sub geocode {
throw RABX::Error("We do not cover Northern Ireland, I'm afraid, as our licence doesn't include any maps for the region.") if $island eq 'I';
$easting = $location->{easting};
$northing = $location->{northing};
- my $xx = os_to_tile($easting);
- my $yy = os_to_tile($northing);
+ my $xx = Page::os_to_tile($easting);
+ my $yy = Page::os_to_tile($northing);
$x = int($xx);
$y = int($yy);
$x -= 1 if ($xx - $x < 0.5);
@@ -887,43 +762,9 @@ sub geocode_string {
$js =~ /center: {lat: (.*?),lng: (.*?)}/;
my $lat = $1; my $lon = $2;
($easting,$northing) = mySociety::GeoUtil::wgs84_to_national_grid($lat, $lon, 'G');
- $x = int(os_to_tile($easting))-1;
- $y = int(os_to_tile($northing))-1;
+ $x = int(Page::os_to_tile($easting))-1;
+ $y = int(Page::os_to_tile($northing))-1;
}
return ($x, $y, $easting, $northing, $error);
}
-# P is easting or northing
-# BL is bottom left tile reference of displayed map
-sub os_to_px {
- my ($p, $bl) = @_;
- return tile_to_px(os_to_tile($p), $bl);
-}
-
-# Convert tile co-ordinates to pixel co-ordinates from top right of map
-# BL is bottom left tile reference of displayed map
-sub tile_to_px {
- my ($p, $bl) = @_;
- $p = 508 - 254 * ($p - $bl);
- $p = int($p + .5 * ($p <=> 0));
- return $p;
-}
-
-# Tile co-ordinates are linear scale of OS E/N
-# Will need more generalising when more zooms appear
-sub os_to_tile {
- return $_[0] / (5000/31);
-}
-sub tile_to_os {
- return $_[0] * (5000/31);
-}
-
-sub click_to_tile {
- my ($pin_tile, $pin, $invert) = @_;
- $pin -= 254 while $pin > 254;
- $pin += 254 while $pin < 0;
- $pin = 254 - $pin if $invert; # image submits measured from top down
- return $pin_tile + $pin / 254;
-}
-
-
diff --git a/web/js.js b/web/js.js
index eb3a52ea1..2016fc381 100644
--- a/web/js.js
+++ b/web/js.js
@@ -51,6 +51,21 @@ YAHOO.util.Event.onContentReady('mapForm', function() {
}
});
+YAHOO.util.Event.onContentReady('another_qn', function() {
+ if (!document.getElementById('been_fixed_no').checked) {
+ YAHOO.util.Dom.setStyle(this, 'display', 'none');
+ }
+ YAHOO.util.Event.addListener('been_fixed_no', 'click', function(e) {
+ YAHOO.util.Dom.setStyle('another_qn', 'display', 'block');
+ });
+ YAHOO.util.Event.addListener('been_fixed_yes', 'click', function(e) {
+ YAHOO.util.Dom.setStyle('another_qn', 'display', 'none');
+ });
+ YAHOO.util.Event.addListener('been_fixed_na', 'click', function(e) {
+ YAHOO.util.Dom.setStyle('another_qn', 'display', 'none');
+ });
+});
+
var timer;
function email_alert_close() {
YAHOO.util.Dom.setStyle('email_alert_box', 'display', 'none');
diff --git a/web/questionnaire.cgi b/web/questionnaire.cgi
new file mode 100755
index 000000000..2f31fac3d
--- /dev/null
+++ b/web/questionnaire.cgi
@@ -0,0 +1,228 @@
+#!/usr/bin/perl -w
+
+# questionnaire.cgi:
+# Questionnaire for problem creators
+#
+# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
+# Email: matthew@mysociety.org. WWW: http://www.mysociety.org
+#
+# $Id: questionnaire.cgi,v 1.1 2007-05-04 14:36:56 matthew Exp $
+
+use strict;
+require 5.8.0;
+
+# Horrible boilerplate to set up appropriate library paths.
+use FindBin;
+use lib "$FindBin::Bin/../perllib";
+use lib "$FindBin::Bin/../../perllib";
+use Error qw(:try);
+
+use Page;
+use mySociety::AuthToken;
+use mySociety::Config;
+use mySociety::DBHandle qw(dbh select_all);
+use mySociety::MaPit;
+use mySociety::Web qw(ent);
+
+BEGIN {
+ mySociety::Config::set_file("$FindBin::Bin/../conf/general");
+ 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)
+ );
+}
+
+sub main {
+ my $q = shift;
+ my $out = '';
+ if ($q->param('submit')) {
+ $out = submit_questionnaire($q);
+ } else {
+ $out = display_questionnaire($q);
+ }
+ print Page::header($q, _('Questionnaire'));
+ print $out;
+ print Page::footer();
+ dbh()->rollback();
+}
+Page::do_fastcgi(\&main);
+
+sub check_stuff {
+ my $q = shift;
+
+ my $id = mySociety::AuthToken::retrieve('questionnaire', $q->param('token'));
+ throw Error::Simple("I'm afraid we couldn't validate that token. If you've copied the URL from an email, please check that you copied it exactly.\n") unless $id;
+
+ my $questionnaire = dbh()->selectrow_hashref(
+ 'select id, problem_id, whenanswered from questionnaire where id=?', {}, $id);
+ my $problem_id = $questionnaire->{problem_id};
+ throw Error::Simple("You have already answered this questionnaire. If you have a question, please <a href=/contact>get in touch</a>, or <a href=/?id=$problem_id>view your problem</a>.\n") if $questionnaire->{whenanswered};
+
+ my $prev_questionnaire = dbh()->selectrow_hashref(
+ 'select id from questionnaire where problem_id=? and whenanswered is not null', {}, $problem_id);
+
+ my $problem = dbh()->selectrow_hashref(
+ "select *, extract(epoch from confirmed) as time, extract(epoch from whensent-confirmed) as whensent
+ from problem where id=? and state in ('confirmed','fixed')", {}, $problem_id);
+ throw Error::Simple("I'm afraid we couldn't locate your problem in the database.\n") unless $problem;
+
+ return ($questionnaire, $prev_questionnaire, $problem);
+}
+
+sub submit_questionnaire {
+ my $q = shift;
+ my @vars = qw(token id been_fixed reported update another);
+ my %input = map { $_ => scalar $q->param($_) } @vars;
+ my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars;
+
+ my ($error, $questionnaire, $prev_questionnaire, $problem);
+ try {
+ ($questionnaire, $prev_questionnaire, $problem) = check_stuff($q);
+ } catch Error::Simple with {
+ my $e = shift;
+ $error = $e;
+ };
+ return $error if $error;
+
+ my @errors;
+ push @errors, 'Please state whether or not the problem has been fixed' unless $input{been_fixed};
+ push @errors, 'Please say whether you\'ve ever reported a problem to your council before' unless $input{reported} || $prev_questionnaire;
+ push @errors, 'Please indicate whether you\'d like to receive another questionnaire'
+ if $input{been_fixed} eq 'No' && !$input{another};
+ push @errors, 'Please provide some explanation as to why you\'re reopening this report'
+ if $input{been_fixed} eq 'No' && $problem->{state} eq 'fixed' && !$input{update};
+ return display_questionnaire($q, @errors) if @errors;
+
+ my $new_state;
+ $new_state = 'fixed' if $input{been_fixed} eq 'Yes' && $problem->{state} eq 'confirmed';
+ $new_state = 'confirmed' if $input{been_fixed} eq 'No' && $problem->{state} eq 'fixed';
+
+ # Record state change, if there was one
+ dbh()->do("update problem set state=? where id=?", {}, $new_state, $problem->{id})
+ if $new_state;
+
+ # Record questionnaire response
+ my $reported = $input{reported} eq 'Yes' ? 't' :
+ ($input{reported} eq 'No' ? 'f' : undef);
+ dbh()->do('update questionnaire set whenanswered=ms_current_timestamp(),
+ ever_reported=? where id=?', {}, $reported, $questionnaire->{id});
+
+ # Record an update if they've given one, or if there's a state change
+ my $name = $problem->{anonymous} ? undef : $problem->{name};
+ my $update = $input{update} ? $input{update} : 'Questionnaire filled in by problem reporter';
+ dbh()->do("insert into comment
+ (problem_id, name, email, website, text, state, mark_fixed, mark_open)
+ values (?, ?, ?, ?, ?, 'confirmed', ?, ?)", {},
+ $problem->{id}, $name, $problem->{email}, '', $update,
+ $new_state eq 'fixed' ? 't' : 'f', $new_state eq 'confirmed' ? 't' : 'f'
+ )
+ if $new_state || $input{update};
+
+ # If they've said they want another questionnaire, mark as such
+ dbh()->do("update problem set send_questionnaire = 't' where id=?", {}, $problem->{id})
+ if $input{been_fixed} eq 'No' && $input{another} eq 'Yes';
+
+ dbh()->commit();
+ return <<EOF;
+<p>Thank you very much for filling in our questionnaire.
+<a href="/?id=$problem->{id}">View your report on the site</a></p>
+EOF
+}
+
+sub display_questionnaire {
+ my ($q, @errors) = @_;
+ my @vars = qw(token id been_fixed reported update another);
+ my %input = map { $_ => scalar $q->param($_) } @vars;
+ my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars;
+
+ my ($error, $questionnaire, $prev_questionnaire, $problem);
+ try {
+ ($questionnaire, $prev_questionnaire, $problem) = check_stuff($q);
+ } catch Error::Simple with {
+ my $e = shift;
+ $error = $e;
+ };
+ return $error if $error;
+
+ my $x = Page::os_to_tile($problem->{easting});
+ my $y = Page::os_to_tile($problem->{northing});
+ my $x_tile = int($x);
+ my $y_tile = int($y);
+ my $px = Page::os_to_px($problem->{easting}, $x_tile);
+ my $py = Page::os_to_px($problem->{northing}, $y_tile);
+
+ my $pins = Page::display_pin($q, $px, $py, $problem->{state} eq 'fixed'?'green':'red');
+ my $problem_text = Page::display_problem_text($q, $problem);
+ my $updates = Page::display_problem_updates($problem->{id});
+ my $out = '';
+ $out .= Page::display_map($q, x => $x_tile, y => $y_tile, pins => $pins,
+ px => $px, py => $py, pre => $problem_text, post => $updates );
+ my %been_fixed = (
+ yes => $input{been_fixed} eq 'Yes' ? ' checked' : '',
+ no => $input{been_fixed} eq 'No' ? ' checked' : '',
+ );
+ my %reported = (
+ yes => $input{reported} eq 'Yes' ? ' checked' : '',
+ no => $input{reported} eq 'No' ? ' checked' : '',
+ );
+ my %another = (
+ yes => $input{another} eq 'Yes' ? ' checked' : '',
+ no => $input{another} eq 'No' ? ' checked' : '',
+ );
+ $out .= <<EOF;
+ <style type="text/css">label { float:none;}</style>
+<h1>Questionnaire</h1>
+<form method="post" action="/questionnaire">
+<input type="hidden" name="token" value="$input_h{token}">
+
+<p>The details of your problem are available on the right hand side of this page.
+EOF
+ $out .= 'Please take a look at the updates that have been left.' if $updates;
+ $out .= '</p>';
+ if (@errors) {
+ $out .= '<ul id="error"><li>' . join('</li><li>', @errors) . '</li></ul>';
+ }
+ $out .= '<p>';
+ $out .= 'An update marked this problem as fixed. ' if $problem->{state} eq 'fixed';
+ $out .= 'Has the problem been fixed?</p>';
+ $out .= <<EOF;
+<p align="center">
+<input type="radio" name="been_fixed" id="been_fixed_yes" value="Yes"$been_fixed{yes}>
+<label for="been_fixed_yes">Yes</label>
+<input type="radio" name="been_fixed" id="been_fixed_no" value="No"$been_fixed{no}>
+<label for="been_fixed_no">No</label>
+</p>
+EOF
+ $out .= <<EOF unless $prev_questionnaire;
+<p>Have you ever reported a problem to your council before?</p>
+<p align="center">
+<input type="radio" name="reported" id="reported_yes" value="Yes"$reported{yes}>
+<label for="reported_yes">Yes</label>
+<input type="radio" name="reported" id="reported_no" value="No"$reported{no}>
+<label for="reported_no">No</label>
+</p>
+EOF
+ $out .= <<EOF;
+<p>If you wish to leave a public update on the problem, please enter it here
+(please note it will not be sent to the council) :</p>
+<p><textarea name="update" style="width:100%" rows="7" cols="30">$input_h{update}</textarea></p>
+
+<div id="another_qn">
+<p>Would you like to receive another questionnaire in 4 weeks, reminding you to check the status?</p>
+<p align="center">
+<input type="radio" name="another" id="another_yes" value="Yes"$another{yes}>
+<label for="another_yes">Yes</label>
+<input type="radio" name="another" id="another_no" value="No"$another{no}>
+<label for="another_no">No</label>
+</p>
+</div>
+
+<p align="right"><input type="submit" name="submit" value="Submit questionnaire"></p>
+</form>
+EOF
+ $out .= Page::display_map_end(0);
+ return $out;
+}