source: trunk/npemap.org.uk/cgi/submit.fcgi @ 251

Last change on this file since 251 was 251, checked in by David Sheldon, 14 years ago

Add google analytics to submit page so we can use their "Goal tracking".

  • Property svn:executable set to *
File size: 5.5 KB
Line 
1#!/usr/bin/perl
2#
3# Copyright (c) 2006 Dominic Hargreaves
4# See accompanying file "LICENCE" for licence details
5
6use strict;
7use warnings;
8
9use DBI;
10use CGI::Fast qw/:standard -debug/;
11use Geo::Postcode;
12
13# Find our private perl libraries
14use FindBin;
15use lib "$FindBin::Bin/../perllib";
16use NPEMap;
17use NPEMap::Postcodes;
18
19# Set up database handler to try and make sure it's ready for the first
20# request
21# No point in handling errors here since they'll get handled by the request
22# handler
23my $dbh = setup_dbh();
24
25my @fields = qw(easting northing postcode1 postcode2);
26my $returnBaseURL = '';
27
28my $googleAnalytics = <<"HERE";
29<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
30</script>
31<script type="text/javascript">
32_uacct = "UA-732621-2";
33if (typeof urchinTracker == 'function') urchinTracker();
34</script>
35HERE
36my $cgi;
37# Process incoming requests
38REQUEST: while ($cgi = new CGI::Fast) {
39
40    # If we're given return URL parameters, basic sanity check to stop
41    # funny business
42   
43    my $returnlink = '<a href="' . $returnBaseURL . '/tiles/map.html">Go back to the map</a>';   
44
45    if (defined $cgi->param('easting') and ($cgi->param('easting') =~ /\d+/) and
46        defined $cgi->param('northing') and ($cgi->param('northing') =~ /\d+/) ) {
47        $returnlink = '<a href="' . $returnBaseURL . '/tiles/map.html#' . int($cgi->param('easting')/1000). ",".int($cgi->param('northing')/1000)  . ',1">Go back to the map</a>';
48    }
49
50
51    # In case the database went away, make sure we have a connection
52    unless ($dbh = setup_dbh()) {
53        print_html_err('Error setting up database connection', $returnlink);
54        next REQUEST;
55    }
56
57    my ($easting, $northing);
58
59    # Input validation
60    foreach my $field (@fields) {
61        unless (defined $cgi->param($field)) {
62            print_html_err ("Parameter '$field' missing", $returnlink);
63            next REQUEST;
64        }
65    }
66
67    # Is the Easting in a valid range?
68    if (($cgi->param('easting') > 700000) or
69        ($cgi->param('easting') < 0)) {
70        print_html_err ("Parameter 'easting' must be an integer between 0 and 700,000", $returnlink);
71        next REQUEST;
72    } else {
73        $easting = $cgi->param('easting');
74    }
75
76    # Is the Northing in a valid range?
77    if (($cgi->param('northing') > 1300000) or
78        ($cgi->param('northing') < 0)) {
79        print_html_err("Parameter 'northing' must be an integer between 0 and 1,300,000", $returnlink);
80        next REQUEST;
81    } else {
82        $northing = $cgi->param('northing');
83    }
84
85    my $sth;
86
87    # Now validate the postcode input format
88    my ($trimmed_1, $trimmed_2) = ($cgi->param('postcode1'), $cgi->param('postcode2'));
89    $trimmed_1 =~ s/^\s+//;
90    $trimmed_2 =~ s/^\s+//;
91    $trimmed_1 =~ s/\s+$//;
92    $trimmed_2 =~ s/\s+$//;
93    my $raw_postcode = $trimmed_1;
94    $raw_postcode .= ' ' . $trimmed_2 if defined $trimmed_2;
95
96    unless ((length($trimmed_2)) == 1 or (length($trimmed_2) == 0) or (length($trimmed_2) == 3) or (!defined $trimmed_2)) {
97        print_html_err("The postcode format is not valid", $returnlink);
98        next REQUEST;
99    }
100
101    my $postcode = Geo::Postcode->new($raw_postcode);
102    my ($first, $second, $third, $fourth) = @{$postcode->fragments};
103    my ($outward, $inward);
104
105    if ($postcode->valid) {
106        # We have a complete postcode; input it straight into the database
107        $outward = $first . $second;
108        $inward = $third . $fourth;
109    } elsif($postcode->valid_fragment) {
110        # We have a valid fragment; let's build up what we can
111        # We are guaranteed to have the first two
112        $outward = $first . $second;
113        $inward = '';
114        $inward .= $third if defined $third;
115        $inward .= $fourth if defined $fourth;
116    } else {
117        print_html_err("The postcode format is not valid", $returnlink);
118        next REQUEST;
119    }
120
121    # Check for a duplicate.
122    # We want to collect duplicates from different IP addresses as a kind of
123    # corroboration factor; this just catches accidental double-submission
124    # really.
125    $sth = $dbh->prepare('SELECT raw_postcode_outward FROM postcodes WHERE raw_postcode_outward = ? AND raw_postcode_inward = ? AND easting = ? AND northing = ? AND ip = ? AND NOT deleted');
126    unless ($sth->execute($cgi->param('postcode1'), $cgi->param('postcode2'), $easting, $northing, $ENV{'REMOTE_ADDR'})) {
127        print_html_err('Database error when checking for duplicate data :(', $returnlink);
128        next REQUEST;
129    }
130
131    if ($sth->rows) {
132        print_html_err('You, or someone with the same IP address, have already submitted this postcode with these co-ordinates.', $returnlink);
133        next REQUEST;
134    }
135
136    $sth = $dbh->prepare('INSERT INTO postcodes (outward, inward, raw_postcode_outward, raw_postcode_inward, easting, northing, ip, source) VALUES (?, ?, ?, ?, ?, ?, ?, 0)');
137    if ($sth->execute($outward, $inward, $cgi->param('postcode1'), $cgi->param('postcode2'), $easting, $northing, $ENV{'REMOTE_ADDR'})) {
138        print "Content-type: text/html\n\n";
139        print "<html><head><title>Thank you</title></head>\n";
140        print "<body><p>Thank you for telling us where your post code is!</p>\n";
141        print "<p>$returnlink</p>\n";
142        print $googleAnalytics;
143        print "</body></html>";
144        # Any extra actions
145        build_home_stats($dbh);
146        next REQUEST;
147    } else {
148        print STDERR "DB error: " . $dbh->errstr . "\n";
149        print_html_err("Database error when adding your data :(", $returnlink);
150        next REQUEST;
151    }
152
153# WE NEVER GET HERE
154
155}
156
157# No more requests to serve, so tidy up
158$dbh->disconnect;
Note: See TracBrowser for help on using the repository browser.