diff options
Diffstat (limited to 'web')
46 files changed, 526 insertions, 6139 deletions
diff --git a/web/about.cgi b/web/about.cgi deleted file mode 100755 index 6b0347ecf..000000000 --- a/web/about.cgi +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# about.cgi: -# For EHA -# -# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: about.cgi,v 1.10 2009-08-03 10:45:28 matthew Exp $ - -use strict; -use Standard -db; - -my $lastmodified = (stat $0)[9]; - -# Main code for index.cgi -sub main { - my $q = shift; - print Page::header($q, title=>_('About us')); - if ($q->{site} eq 'emptyhomes') { - print $q->h1(_('About us')); - print '<div style="float: left; width: 48%;">'; - print _(<<ABOUTUS); -<h2>The Empty Homes Agency</h2> -<p>The Empty Homes agency is an independent campaigning charity. We are not -part of government, and have no formal links with local councils although we -work in cooperation with both. We exist to highlight the waste of empty -property and work with others to devise and promote sustainable solutions to -bring empty property back into use. We are based in London but work across -England. We also work in partnership with other charities across the UK.</p> -ABOUTUS - print '</div> <div style="float: right; width:48%;">'; - print _(<<ABOUTUS); -<h2>Shelter Cymru</h2> -Shelter Cymru is Wales’ people and homes charity and wants everyone in Wales to -have a decent home. We believe a home is a fundamental right and essential to -the health and well-being of people and communities. We work for people in -housing need. We have offices all over Wales and prevent people from losing -their homes by offering free, confidential and independent advice. When -necessary we constructively challenge on behalf of people to ensure they are -properly assisted and to improve practice and learning. We believe that -bringing empty homes back into use can make a significant contribution to the -supply of affordable homes in Wales. -<a href="http://www.sheltercymru.org.uk/shelter/advice/pdetail.asp?cat=20">Further information about our work on -empty homes</a>. -ABOUTUS - print '</div>'; - } - print Page::footer($q); -} -Page::do_fastcgi(\&main, $lastmodified); - diff --git a/web/ajax.cgi b/web/ajax.cgi deleted file mode 100755 index f13529852..000000000 --- a/web/ajax.cgi +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# ajax.cgi: -# Updating the pins as you drag the map -# -# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: ajax.cgi,v 1.19 2009-12-15 17:53:52 louise Exp $ - -use strict; -use Standard; -use mySociety::Web qw(ent NewURL); - -sub main { - my $q = shift; - - my @vars = qw(x y sx sy all_pins); - my %input = map { $_ => $q->param($_) || '' } @vars; - my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; - - # Our current X/Y middle of visible map - my $x = $input{x}; - my $y = $input{y}; - $x ||= 0; $x += 0; - $y ||= 0; $y += 0; - - # Where we started as that's the (0,0) we have to work to - my $sx = $input{sx}; - my $sy = $input{sy}; - $sx ||= 0; $sx += 0; - $sy ||= 0; $sy += 0; - - my $interval; - unless ($input{all_pins}) { - $interval = '6 months'; - } - my ($pins, $on_map, $around_map, $dist) = FixMyStreet::Map::map_pins($q, $x, $y, $sx, $sy, $interval); - my $cobrand = Page::get_cobrand($q); - my $list = ''; - my $link = ''; - foreach (@$on_map) { - $link = Cobrand::url($cobrand, NewURL($q, -retain => 1, - -url => '/report/' . $_->{id}, - pc => undef, - x => undef, - y => undef, - sx => undef, - sy => undef, - all_pins => undef, - no_pins => undef), $q); - $list .= '<li><a href="' . $link . '">'; - $list .= ent($_->{title}) . '</a> <small>('; - $list .= Page::prettify_epoch($q, $_->{time}, 1) . ')</small>'; - $list .= ' <small>' . _('(fixed)') . '</small>' if $_->{state} eq 'fixed'; - $list .= '</li>'; - } - my $om_list = $list; - - $list = ''; - foreach (@$around_map) { - my $dist = int($_->{distance}*10+.5)/10; - $link = Cobrand::url($cobrand, NewURL($q, -retain => 1, - -url => '/report/' . $_->{id}, - pc => undef, - x => undef, - y => undef, - sx => undef, - sy => undef, - all_pins => undef, - no_pins => undef), $q); - $list .= '<li><a href="' . $link . '">'; - $list .= ent($_->{title}) . '</a> <small>('; - $list .= Page::prettify_epoch($q, $_->{time}, 1) . ', '; - $list .= $dist . 'km)</small>'; - $list .= ' <small>' . _('(fixed)') . '</small>' if $_->{state} eq 'fixed'; - $list .= '</li>'; - } - my $am_list = $list; - - #$list = ''; - #foreach (@$fixed) { - # $list .= '<li><a href="/report/' . $_->{id} . '">'; - # $list .= $_->{title} . ' <small>(' . int($_->{distance}*10+.5)/10 . 'km)</small>'; - # $list .= '</a></li>'; - #} - #my $f_list = $list; - - # For now, assume this is not cacheable - may need to be more fine-grained later - print $q->header(-charset => 'utf-8', -content_type => 'text/javascript', -Cache_Control => 'max-age=0'); - - - $pins =~ s/'/\\'/g; - $om_list =~ s/'/\\'/g; - $am_list =~ s/'/\\'/g; - #$f_list =~ s/'/\\'/g; - print <<EOF; -({ -'pins': '$pins', -'current': '$om_list', -'current_near': '$am_list' -}) -EOF -} - -Page::do_fastcgi(\&main); - diff --git a/web/alert.cgi b/web/alert.cgi deleted file mode 100755 index 208dc756b..000000000 --- a/web/alert.cgi +++ /dev/null @@ -1,610 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# alert.cgi: -# Alert code for FixMyStreet -# -# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: alert.cgi,v 1.67 2010-01-06 10:08:22 louise Exp $ - -use strict; -use Standard; -use Digest::SHA1 qw(sha1_hex); -use Encode; -use Error qw(:try); -use CrossSell; -use FixMyStreet::Alert; -use FixMyStreet::Geocode; -use mySociety::AuthToken; -use mySociety::Config; -use mySociety::DBHandle qw(select_all); -use mySociety::EmailUtil qw(is_valid_email); -use mySociety::Gaze; -use mySociety::MaPit; -use mySociety::VotingArea; -use mySociety::Web qw(ent); -use Cobrand; -use Utils; - -sub main { - my $q = shift; - my $out = ''; - my $title = _('Confirmation'); - if ($q->param('signed_email')) { - $out = alert_signed_input($q); - } elsif (my $token = $q->param('token')) { - my $data = mySociety::AuthToken::retrieve('alert', $token); - if ($data->{id}) { - $out = alert_token($q, $data); - } else { - my $contact_url = Cobrand::url(Page::get_cobrand($q), '/contact', $q); - $out = $q->p(sprintf(_(<<EOF), $contact_url)); -Thank you for trying to confirm your alert. We seem to have an error ourselves -though, so <a href="%s">please let us know what went on</a> and we'll look into it. -EOF - my %vars = (error => $out); - my $cobrand_page = Page::template_include('error', $q, Page::template_root($q), %vars); - $out = $cobrand_page if $cobrand_page; - - } - } elsif ($q->param('rss')) { - $out = alert_rss($q); - return unless $out; - } elsif ($q->param('rznvy')) { - $out = alert_do_subscribe($q, $q->param('rznvy')); - } elsif ($q->param('id')) { - $out = alert_updates_form($q); - } elsif ($q->param('type') && $q->param('feed')) { - $title = _('Local RSS feeds and email alerts'); - $out = alert_local_form($q); - } elsif ($q->param('pc') || ($q->param('lat') || $q->param('lon'))) { - $title = _('Local RSS feeds and email alerts'); - $out = alert_list($q); - } else { - $title = _('Local RSS feeds and email alerts'); - $out = alert_front_page($q); - } - - print Page::header($q, title => $title, robots => 'noindex,nofollow'); - print $out; - print Page::footer($q); -} -Page::do_fastcgi(\&main); - -sub alert_list { - my ($q, @errors) = @_; - my @vars = qw(pc rznvy lat lon); - my %input = map { $_ => scalar $q->param($_) } @vars; - my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; - - my($error, $lat, $lon); - if ($input{lat} || $input{lon}) { - $lat = $input{lat}; - $lon = $input{lon}; - } else { - try { - ($lat, $lon, $error) = FixMyStreet::Geocode::lookup($input{pc}, $q); - } catch Error::Simple with { - $error = shift; - }; - } - - return FixMyStreet::Geocode::list_choices($error, '/alert', $q) if ref($error) eq 'ARRAY'; - return alert_front_page($q, $error) if $error; - - my $pretty_pc = $input_h{pc}; - my $pretty_pc_text;# This one isnt't getting the nbsp. - if (mySociety::PostcodeUtil::is_valid_postcode($input{pc})) { - $pretty_pc = mySociety::PostcodeUtil::canonicalise_postcode($input{pc}); - $pretty_pc_text = $pretty_pc; - $pretty_pc_text =~ s/ //g; - $pretty_pc =~ s/ / /; - } - - # truncate the lat,lon for nicer urls - ( $lat, $lon ) = map { Utils::truncate_coordinate($_) } ( $lat, $lon ); - - my $errors = ''; - $errors = '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>' if @errors; - - my $cobrand = Page::get_cobrand($q); - my @types = (Cobrand::area_types($cobrand), @$mySociety::VotingArea::council_child_types); - my %councils = map { $_ => 1 } Cobrand::area_types($cobrand); - - my $areas = mySociety::MaPit::call('point', "4326/$lon,$lat", type => \@types); - my ($success, $error_msg) = Cobrand::council_check($cobrand, { all_councils => $areas }, $q, 'alert'); - if (!$success) { - return alert_front_page($q, $error_msg); - } - - return alert_front_page($q, _('That location does not appear to be covered by a council, perhaps it is offshore - please try somewhere more specific.')) if keys %$areas == 0; - - my ($options, $options_start, $options_end); - if (mySociety::Config::get('COUNTRY') eq 'NO') { - - my (@options, $fylke, $kommune); - foreach (values %$areas) { - if ($_->{type} eq 'NKO') { - $kommune = $_; - } else { - $fylke = $_; - } - } - my $kommune_name = $kommune->{name}; - my $fylke_name = $fylke->{name}; - - if ($fylke->{id} == 3) { # Oslo - - push @options, [ 'council', $fylke->{id}, Page::short_name($fylke), - sprintf(_("Problems within %s"), $fylke_name) ]; - - $options_start = "<div><ul id='rss_feed'>"; - $options = alert_list_options($q, @options); - $options_end = "</ul>"; - - } else { - - push @options, - [ 'area', $kommune->{id}, Page::short_name($kommune), $kommune_name ], - [ 'area', $fylke->{id}, Page::short_name($fylke), $fylke_name ]; - $options_start = '<div id="rss_list">'; - $options = $q->p($q->strong(_('Problems within the boundary of:'))) . - $q->ul(alert_list_options($q, @options)); - @options = (); - push @options, - [ 'council', $kommune->{id}, Page::short_name($kommune), $kommune_name ], - [ 'council', $fylke->{id}, Page::short_name($fylke), $fylke_name ]; - $options .= $q->p($q->strong(_('Or problems reported to:'))) . - $q->ul(alert_list_options($q, @options)); - $options_end = $q->p($q->small(_('FixMyStreet sends different categories of problem -to the appropriate council, so problems within the boundary of a particular council -might not match the problems sent to that council. For example, a graffiti report -will be sent to the district council, so will appear in both of the district -council’s alerts, but will only appear in the "Within the boundary" alert -for the county council.'))) . '</div><div id="rss_buttons">'; - - } - - } elsif (keys %$areas == 2) { - - # One-tier council - my (@options, $council, $ward); - foreach (values %$areas) { - if ($councils{$_->{type}}) { - $council = $_; - } else { - $ward = $_; - } - } - my $council_name = $council->{name}; - my $ward_name = $ward->{name}; - push @options, [ 'council', $council->{id}, Page::short_name($council), - sprintf(_("Problems within %s"), $council_name) ]; - push @options, [ 'ward', $council->{id}.':'.$ward->{id}, Page::short_name($council) . '/' - . Page::short_name($ward), sprintf(_("Problems within %s ward"), $ward_name) ]; - - $options_start = "<div><ul id='rss_feed'>"; - $options = alert_list_options($q, @options); - $options_end = "</ul>"; - - } elsif (keys %$areas == 1) { - - # One-tier council, no ward - my (@options, $council); - foreach (values %$areas) { - $council = $_; - } - my $council_name = $council->{name}; - push @options, [ 'council', $council->{id}, Page::short_name($council), - sprintf(_("Problems within %s"), $council_name) ]; - - $options_start = "<div><ul id='rss_feed'>"; - $options = alert_list_options($q, @options); - $options_end = "</ul>"; - - } elsif (keys %$areas == 4) { - - # Two-tier council - my (@options, $county, $district, $c_ward, $d_ward); - foreach (values %$areas) { - if ($_->{type} eq 'CTY') { - $county = $_; - } elsif ($_->{type} eq 'DIS') { - $district = $_; - } elsif ($_->{type} eq 'CED') { - $c_ward = $_; - } elsif ($_->{type} eq 'DIW') { - $d_ward = $_; - } - } - my $district_name = $district->{name}; - my $d_ward_name = $d_ward->{name}; - my $county_name = $county->{name}; - my $c_ward_name = $c_ward->{name}; - push @options, - [ 'area', $district->{id}, Page::short_name($district), $district_name ], - [ 'area', $district->{id}.':'.$d_ward->{id}, Page::short_name($district) . '/' - . Page::short_name($d_ward), "$d_ward_name ward, $district_name" ], - [ 'area', $county->{id}, Page::short_name($county), $county_name ], - [ 'area', $county->{id}.':'.$c_ward->{id}, Page::short_name($county) . '/' - . Page::short_name($c_ward), "$c_ward_name ward, $county_name" ]; - $options_start = '<div id="rss_list">'; - $options = $q->p($q->strong(_('Problems within the boundary of:'))) . - $q->ul(alert_list_options($q, @options)); - @options = (); - push @options, - [ 'council', $district->{id}, Page::short_name($district), $district_name ], - [ 'ward', $district->{id}.':'.$d_ward->{id}, Page::short_name($district) . '/' . Page::short_name($d_ward), - "$district_name, within $d_ward_name ward" ]; - if ($q->{site} ne 'emptyhomes') { - push @options, - [ 'council', $county->{id}, Page::short_name($county), $county_name ], - [ 'ward', $county->{id}.':'.$c_ward->{id}, Page::short_name($county) . '/' - . Page::short_name($c_ward), "$county_name, within $c_ward_name ward" ]; - $options .= $q->p($q->strong(_('Or problems reported to:'))) . - $q->ul(alert_list_options($q, @options)); - $options_end = $q->p($q->small(_('FixMyStreet sends different categories of problem -to the appropriate council, so problems within the boundary of a particular council -might not match the problems sent to that council. For example, a graffiti report -will be sent to the district council, so will appear in both of the district -council’s alerts, but will only appear in the "Within the boundary" alert -for the county council.'))) . '</div><div id="rss_buttons">'; - } else { - $options_end = ''; - } - } else { - # Hopefully impossible in the UK! - throw Error::Simple('An area with three tiers of council? Impossible! '. $lat . ' ' . $lon . ' ' . join('|',keys %$areas)); - } - - my $dist = mySociety::Gaze::get_radius_containing_population($lat, $lon, 200000); - $dist = int($dist * 10 + 0.5); - $dist = $dist / 10.0; - - my $checked = ''; - $checked = ' checked' if $q->param('feed') && $q->param('feed') eq "local:$lat:$lon"; - my $cobrand_form_elements = Cobrand::form_elements($cobrand, 'alerts', $q); - my $pics = Cobrand::recent_photos($cobrand, 5, $lat, $lon, $dist); - $pics = '<div id="alert_photos">' . $q->h2(_('Photos of recent nearby reports')) . $pics . '</div>' if $pics; - my $header; - if ($pretty_pc) { - $header = sprintf(_('Local RSS feeds and email alerts for ‘%s’'), $pretty_pc); - } else { - $header = _('Local RSS feeds and email alerts'); - } - my $out = $q->h1($header); - my $form_action = Cobrand::url($cobrand, '/alert', $q); - $out .= <<EOF; -<form id="alerts" name="alerts" method="post" action="$form_action"> -<input type="hidden" name="type" value="local"> -<input type="hidden" name="pc" value="$input_h{pc}"> -$cobrand_form_elements -$pics - -EOF - $out .= $q->p(($pretty_pc ? sprintf(_('Here are the types of local problem alerts for ‘%s’.'), $pretty_pc) - : '') . ' ' . _('Select which type of alert you’d like and click the button for an RSS -feed, or enter your email address to subscribe to an email alert.')); - $out .= $errors; - $out .= $q->p(_('The simplest alert is our geographic one:')); - my $rss_label = sprintf(_('Problems within %skm of this location'), $dist); - $out .= <<EOF; -<p id="rss_local"> -<input type="radio" name="feed" id="local:$lat:$lon" value="local:$lat:$lon"$checked> -<label for="local:$lat:$lon">$rss_label</label> -EOF - my $rss_feed; - if ($pretty_pc_text) { - $rss_feed = Cobrand::url($cobrand, "/rss/pc/$pretty_pc_text", $q); - } else { - $rss_feed = Cobrand::url($cobrand, "/rss/l/$lat,$lon", $q); - } - - my $default_link = Cobrand::url($cobrand, "/alert?type=local;feed=local:$lat:$lon", $q); - my $rss_details = _('(a default distance which covers roughly 200,000 people)'); - $out .= $rss_details; - $out .= " <a href='$rss_feed'><img src='/i/feed.png' width='16' height='16' title='" - . _('RSS feed of nearby problems') . "' alt='" . _('RSS feed') . "' border='0'></a>"; - $out .= '</p> <p id="rss_local_alt">' . _('(alternatively the RSS feed can be customised, within'); - my $rss_feed_2k = Cobrand::url($cobrand, $rss_feed.'/2', $q); - my $rss_feed_5k = Cobrand::url($cobrand, $rss_feed.'/5', $q); - my $rss_feed_10k = Cobrand::url($cobrand, $rss_feed.'/10', $q); - my $rss_feed_20k = Cobrand::url($cobrand, $rss_feed.'/20', $q); - $out .= <<EOF; - <a href="$rss_feed_2k">2km</a> / <a href="$rss_feed_5k">5km</a> -/ <a href="$rss_feed_10k">10km</a> / <a href="$rss_feed_20k">20km</a>) -</p> -EOF - $out .= $q->p(_('Or you can subscribe to an alert based upon what ward or council you’re in:')); - $out .= $options_start; - $out .= $options; - $out .= $options_end; - $out .= $q->p('<input type="submit" name="rss" value="' . _('Give me an RSS feed') . '">'); - $out .= $q->p({-id=>'alert_or'}, _('or')); - $out .= '<p>' . _('Your email:') . ' <input type="text" id="rznvy" name="rznvy" value="' . $input_h{rznvy} . '" size="30"></p> -<p><input type="submit" name="alert" value="' . _('Subscribe me to an email alert') . '"></p> -</div> -</form>'; - my %vars = (header => $header, - cobrand_form_elements => $cobrand_form_elements, - error => $errors, - rss_label => $rss_label, - rss_feed => $rss_feed, - default_link => $default_link, - rss_details => $rss_details, - rss_feed_2k => $rss_feed_2k, - rss_feed_5k => $rss_feed_5k, - rss_feed_10k => $rss_feed_10k, - rss_feed_20k => $rss_feed_20k, - lat => $lat, - lon => $lon, - options => $options ); - my $cobrand_page = Page::template_include('alert-options', $q, Page::template_root($q), %vars); - $out = $cobrand_page if ($cobrand_page); - return $out; -} - -sub alert_list_options { - my $q = shift; - my $out = ''; - my $feed = $q->param('feed') || ''; - my $cobrand = Page::get_cobrand($q); - my $cobrand_list = Cobrand::alert_list_options($cobrand, $q, @_); - return $cobrand_list if ($cobrand_list); - foreach (@_) { - my ($type, $vals, $rss, $text) = @$_; - (my $vals2 = $rss) =~ tr{/+}{:_}; - my $id = $type . ':' . $vals . ':' . $vals2; - $out .= '<li><input type="radio" name="feed" id="' . $id . '" '; - $out .= 'checked ' if $feed eq $id; - my $url = "/rss/"; - $url .= $type eq 'area' ? 'area' : 'reports'; - $url .= '/' . $rss ; - my $rss_url = Cobrand::url($cobrand, $url, $q); - $out .= 'value="' . $id . '"> <label for="' . $id . '">' . $text - . '</label> <a href="' . $rss_url . '"><img src="/i/feed.png" width="16" height="16" -title="' . sprintf(_('RSS feed of %s'), $text) . '" alt="' . _('RSS feed') . '" border="0"></a></li>'; - } - return $out; -} - -sub alert_front_page { - my $q = shift; - my $cobrand = Page::get_cobrand($q); - my $error = shift; - my $errors = ''; - $errors = '<ul class="error"><li>' . $error . '</li></ul>' if $error; - - my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } qw(pc); - my $header = _('Local RSS feeds and email alerts'); - my $intro = _('FixMyStreet has a variety of RSS feeds and email alerts for local problems, including -alerts for all problems within a particular ward or council, or all problems -within a certain distance of a particular location.'); - my $pc_label = _('To find out what local alerts we have for you, please enter your GB -postcode or street name and area:'); - my $form_action = Cobrand::url(Page::get_cobrand($q), '/alert', $q); - my $cobrand_form_elements = Cobrand::form_elements($cobrand, 'alerts', $q); - my $cobrand_extra_data = Cobrand::extra_data($cobrand, $q); - my $submit_text = _('Go'); - - my $out = $q->h1($header); - $out .= $q->p($intro); - $out .= $errors . qq(<form method="get" action="$form_action">); - $out .= $q->p($pc_label, '<input type="text" name="pc" value="' . $input_h{pc} . '"> -<input type="submit" value="' . $submit_text . '">'); - $out .= $cobrand_form_elements; - $out .= '</form>'; - - my %vars = (error => $error, - header => $header, - intro => $intro, - pc_label => $pc_label, - form_action => $form_action, - input_h => \%input_h, - submit_text => $submit_text, - cobrand_form_elements => $cobrand_form_elements, - cobrand_extra_data => $cobrand_extra_data, - url_home => Cobrand::url($cobrand, '/', $q)); - - my $cobrand_page = Page::template_include('alert-front-page', $q, Page::template_root($q), %vars); - $out = $cobrand_page if ($cobrand_page); - - return $out if $q->referer() && $q->referer() =~ /fixmystreet\.com/; - my $recent_photos = Cobrand::recent_photos($cobrand, 10); - $out .= '<div id="alert_recent">' . $q->h2(_('Some photos of recent reports')) . $recent_photos . '</div>' if $recent_photos; - - return $out; -} - -sub alert_rss { - my $q = shift; - my $feed = $q->param('feed'); - return alert_list($q, _('Please select the feed you want')) unless $feed; - my $cobrand = Page::get_cobrand($q); - my $base_url = Cobrand::base_url($cobrand); - my $extra_params = Cobrand::extra_params($cobrand, $q); - my $url; - if ($feed =~ /^area:(?:\d+:)+(.*)$/) { - (my $id = $1) =~ tr{:_}{/+}; - $url = $base_url . '/rss/area/' . $id; - $url .= "?" . $extra_params if ($extra_params); - print $q->redirect($url); - return; - } elsif ($feed =~ /^(?:council|ward):(?:\d+:)+(.*)$/) { - (my $id = $1) =~ tr{:_}{/+}; - $url = $base_url . '/rss/reports/' . $id; - $url .= "?" . $extra_params if ($extra_params); - print $q->redirect($url); - return; - } elsif ($feed =~ /^local:([\d\.-]+):([\d\.-]+)$/) { - $url = $base_url . '/rss/l/' . $1 . ',' . $2; - $url .= "?" . $extra_params if ($extra_params); - print $q->redirect($url); - return; - } else { - return alert_list($q, _('Illegal feed selection')); - } -} - -sub alert_updates_form { - my ($q, @errors) = @_; - my @vars = qw(id rznvy); - my %input = map { $_ => $q->param($_) || '' } @vars; - my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; - my $cobrand_form_elements = Cobrand::form_elements(Page::get_cobrand($q), 'alerts', $q); - my $out = ''; - if (@errors) { - $out .= '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>'; - } - $out .= $q->p(_('Receive email when updates are left on this problem.')); - my $label = _('Email:'); - my $subscribe = _('Subscribe'); - my $form_action = Cobrand::url(Page::get_cobrand($q), 'alert', $q); - $out .= <<EOF; -<form action="$form_action" method="post"> -<label class="n" for="alert_rznvy">$label</label> -<input type="text" name="rznvy" id="alert_rznvy" value="$input_h{rznvy}" size="30"> -<input type="hidden" name="id" value="$input_h{id}"> -<input type="hidden" name="type" value="updates"> -<input type="submit" value="$subscribe"> -$cobrand_form_elements -</form> -EOF - return $out; -} - -sub alert_local_form { - my ($q, @errors) = @_; - my @vars = qw(id rznvy feed); - my %input = map { $_ => $q->param($_) || '' } @vars; - my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; - my $cobrand_form_elements = Cobrand::form_elements(Page::get_cobrand($q), 'alerts', $q); - my $out = ''; - if (@errors) { - $out .= '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>'; - } - $out .= $q->p(_('Receive alerts on new local problems')); - my $label = _('Email:'); - my $subscribe = _('Subscribe'); - my $form_action = Cobrand::url(Page::get_cobrand($q), 'alert', $q); - $out .= <<EOF; -<form action="$form_action" method="post"> -<label class="n" for="alert_rznvy">$label</label> -<input type="text" name="rznvy" id="alert_rznvy" value="$input_h{rznvy}" size="30"> -<input type="hidden" name="feed" value="$input_h{feed}"> -<input type="hidden" name="type" value="local"> -<input type="submit" value="$subscribe"> -$cobrand_form_elements -</form> -EOF - return $out; -} - -sub alert_signed_input { - my $q = shift; - my ($salt, $signed_email) = split /,/, $q->param('signed_email'); - my $email = $q->param('rznvy'); - my $id = $q->param('id'); - my $secret = scalar(dbh()->selectrow_array('select secret from secret')); - my $out; - my $cobrand = Page::get_cobrand($q); - if ($signed_email eq sha1_hex("$id-$email-$salt-$secret")) { - my $alert_id = FixMyStreet::Alert::create($email, 'new_updates', $cobrand, '', $id); - FixMyStreet::Alert::confirm($alert_id); - $out = $q->p(_('You have successfully subscribed to that alert.')); - my $cobrand = Page::get_cobrand($q); - my $display_advert = Cobrand::allow_crosssell_adverts($cobrand); - if ($display_advert) { - $out .= CrossSell::display_advert($q, $email); - } - } else { - $out = $q->p(_('We could not validate that alert.')); - } - return $out; -} - -sub alert_token { - my ($q, $data) = @_; - my $id = $data->{id}; - my $type = $data->{type}; - my $email = $data->{email}; - - (my $domain = $email) =~ s/^.*\@//; - if (dbh()->selectrow_array('select email from abuse where lower(email)=? or lower(email)=?', {}, lc($email), lc($domain))) { - return $q->p('Sorry, there has been an error confirming your alert.'); - } - - my $out; - my $cobrand = Page::get_cobrand($q); - my $message; - my $display_advert = Cobrand::allow_crosssell_adverts($cobrand); - if ($type eq 'subscribe') { - FixMyStreet::Alert::confirm($id); - $message = _('You have successfully confirmed your alert.'); - $out = $q->p($message); - if ($display_advert) { - $out .= CrossSell::display_advert($q, $email); - } - } elsif ($type eq 'unsubscribe') { - FixMyStreet::Alert::delete($id); - $message = _('You have successfully deleted your alert.'); - $out = $q->p($message); - if ($display_advert) { - $out .= CrossSell::display_advert($q, $email); - } - } - - my %vars = (message => $message, - url_home => Cobrand::url($cobrand, '/', $q)); - my $confirmation = Page::template_include('confirmed-alert', $q, Page::template_root($q), %vars); - return $confirmation if $confirmation; - return $out; -} - -sub alert_do_subscribe { - my ($q, $email) = @_; - - my $type = $q->param('type'); - - my @errors; - push @errors, _('Please enter a valid email address') unless is_valid_email($email); - push @errors, _('Please select the type of alert you want') if $type && $type eq 'local' && !$q->param('feed'); - if (@errors) { - return alert_updates_form($q, @errors) if $type && $type eq 'updates'; - return alert_list($q, @errors) if $type && $type eq 'local'; - return alert_front_page($q, @errors); - } - - my $alert_id; - my $cobrand = Page::get_cobrand($q); - my $cobrand_data = Cobrand::extra_alert_data($cobrand, $q); - if ($type eq 'updates') { - my $id = $q->param('id'); - $alert_id = FixMyStreet::Alert::create($email, 'new_updates', $cobrand, $cobrand_data, $id); - } elsif ($type eq 'problems') { - $alert_id = FixMyStreet::Alert::create($email, 'new_problems', $cobrand, $cobrand_data); - } elsif ($type eq 'local') { - my $feed = $q->param('feed'); - if ($feed =~ /^area:(?:\d+:)?(\d+)/) { - $alert_id = FixMyStreet::Alert::create($email, 'area_problems', $cobrand, $cobrand_data, $1); - } elsif ($feed =~ /^council:(\d+)/) { - $alert_id = FixMyStreet::Alert::create($email, 'council_problems', $cobrand, $cobrand_data, $1, $1); - } elsif ($feed =~ /^ward:(\d+):(\d+)/) { - $alert_id = FixMyStreet::Alert::create($email, 'ward_problems', $cobrand, $cobrand_data, $1, $2); - } elsif ($feed =~ m{ \A local: ( [\+\-]? \d+ \.? \d* ) : ( [\+\-]? \d+ \.? \d* ) }xms ) { - my $lat = $1; - my $lon = $2; - $alert_id = FixMyStreet::Alert::create($email, 'local_problems', $cobrand, $cobrand_data, $lon, $lat); - } - } else { - throw FixMyStreet::Alert::Error('Invalid type'); - } - - my %h = (); - $h{url} = Page::base_url_with_lang($q, undef, 1) . '/A/' - . mySociety::AuthToken::store('alert', { id => $alert_id, type => 'subscribe', email => $email } ); - dbh()->commit(); - return Page::send_confirmation_email($q, $email, undef, 'alert', %h); -} - diff --git a/web/cobrands/.gitignore b/web/cobrands/.gitignore deleted file mode 100644 index 911c95650..000000000 --- a/web/cobrands/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/cities
\ No newline at end of file diff --git a/web/css/cobrands/emptyhomes/emptyhomes.css b/web/cobrands/emptyhomes/css.css index 61db27054..c45e9255f 100644 --- a/web/css/cobrands/emptyhomes/emptyhomes.css +++ b/web/cobrands/emptyhomes/css.css @@ -61,11 +61,11 @@ a:hover, a:active { background-color: #B1BECF; } -blockquote { +#mysociety blockquote { border-left: solid 4px #013B63; } -.a { +#mysociety .a { color: #000000; background-color: #DCDCED; /* #427499; */ background-color: #B1BECF; @@ -147,6 +147,24 @@ blockquote { background-position: 100% 0; } +#meta { + clear: right; + float: right; + list-style-type: none; + margin: 0.25em 0.5em 0 1em; + padding: 0; + font-size: 83%; +} +#meta li { + display: inline; + margin: 0; + padding: 0 0 0 0.25em; + border-left: solid 1px #B1BECF; +} +#meta li:first-child { + border-left: none; +} + #logo { border: none; position: absolute; @@ -172,28 +190,28 @@ blockquote { color: #FFFFFF; } -#postcodeForm { +#mysociety #postcodeForm { background-color: #80AE7D; color: #000000; font-size: 130%; } -#front_stats div { +#mysociety #front_stats div { background-color: #80AE7D; color: #000000; /*padding: 0.5em 0; */ width: 9em; } -#problem_form { +#mysociety #problem_form { clear: both; } -#alert_links_area { +#mysociety #alert_links_area { margin-top: 1px; } -#eha_advert { +#mysociety #eha_advert { clear: both; width: 55%; margin: 0 auto; @@ -203,7 +221,7 @@ blockquote { border: solid 1px #ff9900; } -#front_intro { +#mysociety #front_intro { margin-bottom: 1em; } diff --git a/web/cobrands/southampton/css.css b/web/cobrands/southampton/css.css index 85f66dcc3..fa0e07548 100644 --- a/web/cobrands/southampton/css.css +++ b/web/cobrands/southampton/css.css @@ -1,22 +1,17 @@ #mysociety #map_box { - width: 380px; + width: 422px; } #mysociety #map, #mysociety #drag { - width: 378px; - height: 378px; -} -#mysociety #watermark { - background: url("/i/mojwatermark-378.png"); - height: 84px; - width: 171px; - position: absolute; - bottom: 0; - right: 0; + width: 420px; + height: 420px; } #mysociety p#fixed, #mysociety p#unknown { - margin-right: 400px; + margin-right: 442px; width: auto; } +#mysociety #problem_form { + clear: both; +} #mysociety h1 { margin: 0; font-size: 175%; diff --git a/web/cobrands/southampton/css.scss b/web/cobrands/southampton/css.scss index 57cb95a8f..0760c982c 100644 --- a/web/cobrands/southampton/css.scss +++ b/web/cobrands/southampton/css.scss @@ -1,4 +1,4 @@ -$map_width: 378px; +$map_width: 420px; $background: #E9EEF7; $darker: #768EB5; @@ -13,20 +13,16 @@ $darker: #768EB5; width: $map_width; height: $map_width; } - #watermark { - background: url("/i/mojwatermark-378.png"); - height: 84px; - width: 171px; - position: absolute; - bottom: 0; - right: 0; - } p#fixed, p#unknown { margin-right: $map_width + 22px; width: auto; } + #problem_form { + clear: both; + } + // Generics h1 { diff --git a/web/confirm.cgi b/web/confirm.cgi deleted file mode 100755 index c4a37c67f..000000000 --- a/web/confirm.cgi +++ /dev/null @@ -1,247 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# confirm.cgi: -# Confirmation code for FixMyStreet -# -# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: confirm.cgi,v 1.66 2009-12-15 18:26:11 louise Exp $ - -use strict; -use Standard; -use Digest::SHA1 qw(sha1_hex); -use CrossSell; -use FixMyStreet::Alert; -use mySociety::AuthToken; -use mySociety::Random qw(random_bytes); - -sub main { - my $q = shift; - my $cobrand = Page::get_cobrand($q); - my $out = ''; - my $token = $q->param('token'); - my $type = $q->param('type') || ''; - my $tokentype = $type eq 'questionnaire' ? 'update' : $type; - my $data = mySociety::AuthToken::retrieve($tokentype, $token); - if ($data) { - if ($type eq 'update') { - $out = confirm_update($q, $data); - } elsif ($type eq 'problem') { - $out = confirm_problem($q, $data); - } elsif ($type eq 'questionnaire') { - $out = add_questionnaire($q, $data, $token); - } - dbh()->commit(); - } else { - my $contact_url = Cobrand::url($cobrand, '/contact', $q); - $out = $q->p(sprintf(_(<<EOF), $contact_url)); -Thank you for trying to confirm your update or problem. We seem to have an -error ourselves though, so <a href="%s">please let us know what went on</a> -and we'll look into it. -EOF - - my %vars = (error => $out); - my $cobrand_page = Page::template_include('error', $q, Page::template_root($q), %vars); - $out = $cobrand_page if $cobrand_page; - } - - print Page::header($q, title=>_('Confirmation')); - print $out; - print Page::footer($q); -} -Page::do_fastcgi(\&main); - -sub confirm_update { - my ($q, $data) = @_; - my $cobrand = Page::get_cobrand($q); - my $id = $data; - my $add_alert = 0; - if (ref($data)) { - $id = $data->{id}; - $add_alert = $data->{add_alert}; - } - - my ($problem_id, $fixed, $email, $name, $cobrand_data) = dbh()->selectrow_array( - "select problem_id, mark_fixed, email, name, cobrand_data from comment where id=?", {}, $id); - $email = lc($email); - - (my $domain = $email) =~ s/^.*\@//; - if (dbh()->selectrow_array('select email from abuse where lower(email)=? or lower(email)=?', {}, $email, $domain)) { - dbh()->do("update comment set state='hidden' where id=?", {}, $id); - return $q->p('Sorry, there has been an error confirming your update.'); - } else { - dbh()->do("update comment set state='confirmed', confirmed=ms_current_timestamp() where id=? and state='unconfirmed'", {}, $id); - } - - my $creator_fixed = 0; - if ($fixed) { - dbh()->do("update problem set state='fixed', lastupdate = ms_current_timestamp() - where id=? and state='confirmed'", {}, $problem_id); - # If a problem reporter is marking their own problem as fixed, turn off questionnaire sending - $creator_fixed = dbh()->do("update problem set send_questionnaire='f' where id=? and lower(email)=? - and send_questionnaire='t'", {}, $problem_id, $email); - } else { - # Only want to refresh problem if not already fixed - dbh()->do("update problem set lastupdate = ms_current_timestamp() - where id=? and state='confirmed'", {}, $problem_id); - } - - my $out = ''; - if ($creator_fixed > 0 && $q->{site} ne 'emptyhomes') { - my $answered_ever_reported = dbh()->selectrow_array( - 'select id from questionnaire where problem_id in (select id from problem where lower(email)=?) and ever_reported is not null', {}, $email); - if (!$answered_ever_reported) { - $out = ask_questionnaire($q->param('token'), $q); - } - } - - my $report_url = Cobrand::url($cobrand, "/report/$problem_id#update_$id", $q); - if (!$out) { - $out = $q->p({class => 'confirmed'}, sprintf(_('You have successfully confirmed your update and you can now <a href="%s">view it on the site</a>.'), $report_url)); - my $display_advert = Cobrand::allow_crosssell_adverts($cobrand); - if ($display_advert) { - $out .= CrossSell::display_advert($q, $email, $name); - } - my %vars = ( - url_report => $report_url, - url_home => Cobrand::url($cobrand, '/', $q), - ); - my $cobrand_page = Page::template_include('confirmed-update', $q, Page::template_root($q), %vars); - $out = $cobrand_page if $cobrand_page; - } - - # Subscribe updater to email updates if requested - if ($add_alert) { - my $alert_id = FixMyStreet::Alert::create($email, 'new_updates', $cobrand, $cobrand_data, $problem_id); - FixMyStreet::Alert::confirm($alert_id); - } - - return $out; -} - -sub confirm_problem { - my ($q, $id) = @_; - my $cobrand = Page::get_cobrand($q); - my ($council, $email, $name, $cobrand_data) = dbh()->selectrow_array("select council, email, name, cobrand_data from problem where id=?", {}, $id); - - (my $domain = $email) =~ s/^.*\@//; - if (dbh()->selectrow_array('select email from abuse where lower(email)=? or lower(email)=?', {}, lc($email), lc($domain))) { - dbh()->do("update problem set state='hidden', lastupdate=ms_current_timestamp() where id=?", {}, $id); - return $q->p(_('Sorry, there has been an error confirming your problem.')); - } else { - dbh()->do("update problem set state='confirmed', confirmed=ms_current_timestamp(), lastupdate=ms_current_timestamp() - where id=? and state='unconfirmed'", {}, $id); - } - my $out; - if ($q->{site} eq 'emptyhomes') { - if ($council) { - $out = $q->p(_('Thank you for reporting an empty property on -ReportEmptyHomes.com. We have emailed the lead officer for empty homes in the council -responsible with details, and asked them to do whatever they can to get the -empty property back into use as soon as possible.')) . -$q->p(_('It is worth noting however that the process can sometimes be slow, -especially if the property is in very poor repair or the owner is unwilling to -act. In most cases it can take six months or more before you can expect to see -anything change and sometimes there may be considerable barries to a property -being brought back into use. This doesn’t mean the council isn’t -doing anything. We encourage councils to update the website so you can -see what is happening. It may be a long process, but you reporting your -concerns about this property to the council is a valuable first step.')) . -$q->p(_('We may contact you periodically to ask if anything has changed -with the property you reported.')) . -$q->p(_('Thank you for using ReportEmptyHomes.com. Your action is already helping -to resolve the UK’s empty homes crisis.')) . -$q->p('<a href="/report/' . $id . '">' . _('View your report') . '</a>.'); - } else { - $out = $q->p(_('Thank you for reporting this empty property on ReportEmptyHomes.com. -At present the report cannot be sent through to the council for this area. We -are working with councils to link them into the system so that as many areas -as possible will be covered.')) . -$q->p('<a href="/report/' . $id . '">' . _('View your report') . '</a>.'); - } - } else { - my $report_url = Cobrand::url($cobrand, "/report/$id", $q); - $out = $q->p({class => 'confirmed'}, - _('You have successfully confirmed your problem') - . ($council ? _(' and <strong>we will now send it to the council</strong>') : '') - . sprintf(_('. You can <a href="%s">view the problem on this site</a>.'), $report_url) - ); - my $display_advert = Cobrand::allow_crosssell_adverts($cobrand); - if ($display_advert) { - $out .= CrossSell::display_advert($q, $email, $name); - } - my %vars = ( - url_report => $report_url, - url_home => Cobrand::url($cobrand, '/', $q), - ); - my $cobrand_page = Page::template_include('confirmed-problem', $q, Page::template_root($q), %vars); - $out = $cobrand_page if $cobrand_page; - } - - # Subscribe problem reporter to email updates - my $alert_id = FixMyStreet::Alert::create($email, 'new_updates', $cobrand, $cobrand_data, $id); - FixMyStreet::Alert::confirm($alert_id); - - return $out; -} - -sub ask_questionnaire { - my ($token, $q) = @_; - my $cobrand = Page::get_cobrand($q); - my $qn_thanks = _("Thanks, glad to hear it's been fixed! Could we just ask if you have ever reported a problem to a council before?"); - my $yes = _('Yes'); - my $no = _('No'); - my $go = _('Submit'); - my $form_action = Cobrand::url($cobrand, "/confirm", $q); - my $form_extra_elements = Cobrand::form_elements($cobrand, 'questionnaire', $q); - my $out = <<EOF; -<form action="$form_action" method="post" id="questionnaire"> -<input type="hidden" name="type" value="questionnaire"> -<input type="hidden" name="token" value="$token"> -<p>$qn_thanks</p> -<p align="center"> -<input type="radio" name="reported" id="reported_yes" value="Yes"> -<label for="reported_yes">$yes</label> -<input type="radio" name="reported" id="reported_no" value="No"> -<label for="reported_no">$no</label> -$form_extra_elements -<input type="submit" value="$go"> -</p> -</form> -EOF - my %vars = (form => $out, - url_home => Cobrand::url($cobrand, '/', $q)); - my $cobrand_template = Page::template_include('update-questionnaire', $q, Page::template_root($q), %vars); - $out = $cobrand_template if $cobrand_template; - return $out; -} - -sub add_questionnaire { - my ($q, $data, $token) = @_; - - my $id = $data; - if (ref($data)) { - $id = $data->{id}; - } - my $cobrand = Page::get_cobrand($q); - my ($problem_id, $email, $name) = dbh()->selectrow_array("select problem_id, email, name from comment where id=?", {}, $id); - my $reported = $q->param('reported') || ''; - $reported = $reported eq 'Yes' ? 't' : ($reported eq 'No' ? 'f' : undef); - return ask_questionnaire($token, $q) unless $reported; - my $already = dbh()->selectrow_array("select id from questionnaire - where problem_id=? and old_state='confirmed' and new_state='fixed'", - {}, $problem_id); - dbh()->do("insert into questionnaire (problem_id, whensent, whenanswered, - ever_reported, old_state, new_state) values (?, ms_current_timestamp(), - ms_current_timestamp(), ?, 'confirmed', 'fixed');", {}, $problem_id, $reported) - unless $already; - my $report_url = Cobrand::url($cobrand, "/report/$problem_id", $q); - my $out = $q->p({class => 'confirmed'}, sprintf(_('Thank you — you can <a href="%s">view your updated problem</a> on the site.'), $report_url)); - my $display_advert = Cobrand::allow_crosssell_adverts($cobrand); - if ($display_advert) { - $out .= CrossSell::display_advert($q, $email, $name); - } - return $out; -} - 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; -} - diff --git a/web/css/_main.scss b/web/css/_main.scss index 44fd82b3b..9063f1484 100644 --- a/web/css/_main.scss +++ b/web/css/_main.scss @@ -41,6 +41,14 @@ select, input, textarea { #front_stats div { background-color: $header_back; } + + p.promo { + border-top: 1px solid #bbb; + border-bottom: 1px solid #bbb; + background-color: #eee; + text-align: center; + padding: 0 0.5em; + } } @@ -79,7 +87,23 @@ select, input, textarea { /* Can't put the margin in #mysociety because of above IE craziness */ #wrapper { - margin: 2em; + margin: 1em 2em 2em; +} + +#meta { + list-style-type: none; + margin: 0.25em 0 0 1em; + padding: 0; + font-size: 0.875em; + li { + display: inline; + margin: 0; + padding: 0 0 0 0.25em; + border-left: solid 1px $header_colour; + } + li:first-child { + border-left: none; + } } .v { @@ -111,6 +135,12 @@ select, input, textarea { a:hover, a:active { background-color: $header_colour; color: $header_back; + -moz-border-radius-topleft: 0.5em; + -webkit-border-top-left-radius: 0.5em; + border-radius-top-left: 0.5em; + -moz-border-radius-topright: 0.5em; + -webkit-border-top-right-radius: 0.5em; + border-radius-top-right: 0.5em; } } @@ -129,11 +159,10 @@ select, input, textarea { #footer { clear: both; - text-align: right; - font-size: 83%; - border-top: solid 1px $header_colour; - display: table; - margin: 2em 0 1em auto; - padding: 2px 4px; + text-align: center; + border-top: solid 2px $header_back; + width: 50%; + margin: 2em auto 0; + padding: 1em; } diff --git a/web/css/cobrands/.gitignore b/web/css/cobrands/.gitignore deleted file mode 100644 index 911c95650..000000000 --- a/web/css/cobrands/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/cities
\ No newline at end of file diff --git a/web/css/core.css b/web/css/core.css index b31e6bc0a..d468f097d 100644 --- a/web/css/core.css +++ b/web/css/core.css @@ -13,7 +13,7 @@ color: #666666; background-color: #cccccc; } -#mysociety p.error { +#mysociety p.dev-site-notice, #mysociety p.error { text-align: center; color: #cc0000; font-size: larger; @@ -43,6 +43,7 @@ #mysociety #advert_thin { width: 50%; margin: 1em auto; + text-align: center; border-top: dotted 1px #999999; } #mysociety #advert_hfymp { @@ -145,6 +146,20 @@ padding: 5px; text-align: center; } +#mysociety #form_sign_in_yes { + float: left; + width: 47%; + padding-right: 1%; + border-right: solid 1px #999999; + margin-bottom: 1em; +} +#mysociety #form_sign_in_no, #mysociety #fieldset #form_sign_in_no { + float: right; + width: 47%; + padding-left: 1%; + clear: none; + margin-bottom: 1em; +} #mysociety #watermark { background: url("/i/mojwatermark6.png"); height: 113px; @@ -162,6 +177,7 @@ } #mysociety p#copyright { float: right; + text-align: right; margin: 0 0 1em 0; font-size: 78%; } @@ -263,6 +279,9 @@ margin-top: 0.5em; margin-bottom: 0; } +#mysociety #nearby_lists li small { + color: #666666; +} #mysociety #alert_links { float: right; } @@ -363,6 +382,11 @@ margin-top: 2em; } +.olControlAttribution { + bottom: 3px !important; + left: 3px; +} + @media print { #mysociety #map_box { float: none; diff --git a/web/css/core.scss b/web/css/core.scss index 8bbebfce1..22bdc3d2e 100644 --- a/web/css/core.scss +++ b/web/css/core.scss @@ -29,7 +29,7 @@ $map_width: 500px; background-color: #cccccc; } - p.error { + p.dev-site-notice, p.error { text-align: center; color: #cc0000; font-size: larger; @@ -66,6 +66,7 @@ $map_width: 500px; #advert_thin { width: 50%; margin: 1em auto; + text-align: center; border-top: dotted 1px #999999; } #advert_hfymp { @@ -189,6 +190,22 @@ $map_width: 500px; text-align: center; } + #form_sign_in_yes { + float: left; + width: 47%; + padding-right: 1%; + border-right: solid 1px #999999; + margin-bottom: 1em; + } + + #form_sign_in_no, #fieldset #form_sign_in_no { + float: right; + width: 47%; + padding-left: 1%; + clear: none; + margin-bottom: 1em; + } + // Map #watermark { @@ -210,6 +227,7 @@ $map_width: 500px; p#copyright { float: right; + text-align: right; margin: 0 0 1em 0; font-size: 78%; } @@ -325,6 +343,11 @@ $map_width: 500px; margin-top: 0.5em; margin-bottom: 0; } + + #nearby_lists li small { + color: #666666; + } + #alert_links { float: right; } @@ -491,6 +514,11 @@ $map_width: 500px; } +.olControlAttribution { + bottom: 3px !important; + left: 3px; +} + // Printing, SCSS doesn't handle @media nesting @media print { diff --git a/web/css/main-scambs.css b/web/css/main-scambs.css deleted file mode 100644 index 52f01ffcf..000000000 --- a/web/css/main-scambs.css +++ /dev/null @@ -1,46 +0,0 @@ -ul#error { - padding-top: 4px; - padding-bottom: 4px; -} - -blockquote { - border-left: solid 4px #013B63; -} - -.a { - color: #000000; - background-color: #427499; -} - -#postcodeForm, #front_stats div { - background-color: #427499; - color: #ffffff; -} - -#front_stats div { - padding: 0.5em 0; - width: 7em; -} - -/* Smaller map */ -#map_box { - width: 380px; -} -#map, #drag { - width: 378px; - height: 378px; -} -#watermark { - display: none; - background: url("/i/mojwatermark-378.png"); - height: 84px; - width: 171px; - position: absolute; - bottom: 0; - right: 0; -} - -#fixed, #unknown { - margin-right: 400px; -} - diff --git a/web/css/main.css b/web/css/main.css index ddea37970..5b4be5ebc 100644 --- a/web/css/main.css +++ b/web/css/main.css @@ -43,6 +43,13 @@ select, input, textarea { #mysociety #front_stats div { background-color: #e3d595; } +#mysociety p.promo { + border-top: 1px solid #bbb; + border-bottom: 1px solid #bbb; + background-color: #eee; + text-align: center; + padding: 0 0.5em; +} #header { font-size: 200%; @@ -77,7 +84,23 @@ select, input, textarea { /* Can't put the margin in #mysociety because of above IE craziness */ #wrapper { - margin: 2em; + margin: 1em 2em 2em; +} + +#meta { + list-style-type: none; + margin: 0.25em 0 0 1em; + padding: 0; + font-size: 0.875em; +} +#meta li { + display: inline; + margin: 0; + padding: 0 0 0 0.25em; + border-left: solid 1px #5e552b; +} +#meta li:first-child { + border-left: none; } .v { @@ -108,6 +131,12 @@ select, input, textarea { #navigation a:hover, #navigation a:active { background-color: #5e552b; color: #e3d595; + -moz-border-radius-topleft: 0.5em; + -webkit-border-top-left-radius: 0.5em; + border-radius-top-left: 0.5em; + -moz-border-radius-topright: 0.5em; + -webkit-border-top-right-radius: 0.5em; + border-radius-top-right: 0.5em; } #nav_new a { @@ -125,10 +154,9 @@ select, input, textarea { #footer { clear: both; - text-align: right; - font-size: 83%; - border-top: solid 1px #5e552b; - display: table; - margin: 2em 0 1em auto; - padding: 2px 4px; + text-align: center; + border-top: solid 2px #e3d595; + width: 50%; + margin: 2em auto 0; + padding: 1em; } diff --git a/web/css/scambs.css b/web/css/scambs.css deleted file mode 100644 index 38733d294..000000000 --- a/web/css/scambs.css +++ /dev/null @@ -1,1110 +0,0 @@ -/************************************************/
-/* scambs_web.css */
-/* Use for website and ActiveEdit */
-/************************************************/
-
-/***********************************************/
-/* HTML tag styles */
-/***********************************************/
-
-html {
- margin: 0px 10px;
- background: #E3E3CB;
- border-left: #999 solid 1px;
- border-right: #999 solid 1px;
-}
-/*added an extra pixel to make sure the background lines are seen in all browsers, especialy Opera*/
-
-body {
- margin: 0px;
- color: #333;
- padding: 0px;
- min-height: 100%;
- background: #fff;
- font-family: Verdana, Arial, Helvetica, sans-serif;
-}
-
-* html body {
- margin: 0px 10px;
- border-left: #999 solid 1px;
- border-right: #999 solid 1px;
- height: 100%;
-}
-
-a {
- color: #336699;
- text-decoration: none;
-}
-
-a:link{
- color: #336699;
- text-decoration: none;
-}
-
-a:visited{
- color: #336699;
- text-decoration: none;
-}
-
-a:hover{
- color: #666;
- text-decoration: underline;
-}
-
-a:active, a:focus {
- color: #fff;
- background: #660000;
-}
-
-form {
- margin: 0px;
-}
-
-h1 {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 1em;
- color: #003366;
- text-transform: uppercase;
- font-weight: bold;
- letter-spacing: 0.1em;
-}
-
-h2{
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 1em;
- line-height: 1.2em;
- font-weight: bold;
- color: #006699;
-}
-
-h3{
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 1em;
- line-height: 1.1em;
- color: #003366;
-}
-
-h4{
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 1em;
- line-height: 1em;
- color: #000000;
-}
-
-ul li {
- list-style-type: disc;
- font-size: 1em;
-}
-
-
-ol li {
- list-style-type: decimal;
-}
-
-img {
- border: 0px;
-}
-
-th {
- color: #000000;
- text-align: left;
-}
-
-/* Structured Pages Styles */
-
-#menupanel span.year {
- font-size: 1.2em;
-}
-
-#centrepanel table.listings {
- border: 1px solid #006699;
- width: 100%;
-}
-
-#centrepanel th {
- color: #003366;
- text-align: left;
- border-bottom: 1px solid #006699;
-}
-
-#centrepanel th.day {
- width: 40px;
-}
-
-#centrepanel th.date {
- width: 100px;
-}
-
-#centrepanel th.type {
- width: 60px;
-}
-
-.lefttop
-{
- text-align: left;
- vertical-align:top;
-}
-
-/*** Search Result Styles***/
-
-table.searchresults td {
- text-align: left;
- vertical-align: top;
-}
-
-tr.resultrow td {
- background: #eee;
-}
-
-tr.result td {
- padding-bottom: 20px;
-}
-
-span.resultdate {
- color: #006699;
- font-style: italic;
-}
-
-/***********************************************/
-/* Layout Divs */
-/***********************************************/
-/* Skip content links*/
-a.skip {
- float: left;
- position: absolute; left: -500em; width: 20em;
-}
-
-.test {
- background: url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-y 180px 0px;
- min-height: 1000px;
- height: 100%;
- clear: both;
- }
-
-/*allcontent*/
-#content{
- background: url(http://www.scambs.gov.uk/system/images/scambs/bgdots_right.gif) repeat-y top right;
- width: 100%;
- height: 100%;
- margin: 0px;
- clear: both;
-}
-
-#contentnodots{
- width: 100%;
- height: 100%;
- margin: 0px;
- clear: both;
-}
-
-/*top layer*/
-#top {
- clear: both;
- height: 1.7em;
- padding: 0px 0px 0px 0px;
- border-bottom: 1px solid #fff;
- background: #013B63 url(http://www.scambs.gov.uk/system/images/scambs/topbck.jpg) repeat-y;
-}
-
-#topnav {
- padding: 4px 10px 0px 15px;
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-weight: bold;
- font-size: 0.7em;
- text-align: right;
- color: #fff;
-}
-
-#topnav a:link {
- color: #fff;
-}
-
-#topnav a:visited {
- color: #fff;
-}
-#topnav a:hover {
- color: #CCCCCC;
-}
-
-#topnav a:active, #topnav a:focus {
- color: #fff;
-}
-
-#topnav ul, #topnav li {
- display: inline;
- margin: 0px;
- }
-
-/***********************************************/
-
-.floatleft {
- float: left;
-}
-
-.floatright {
- float: right;
-}
-
-.block {
- display: block;
-}
-
-.clear {
- clear: both;
-}
-
-/*use for hidden text */
-.hide {
- display: none;
-}
-
-.uline {
- text-decoration: underline;
-}
-
-.italic {
- text-decoration: italic;
-}
-
-.dotted {
-background: url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-x left center;
-height: 1px;
-}
-
-.dottedgreyback {
-background: #f7f7f7 url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-x left center;
-height: 1px;
-}
-
-.greyback {
-background: #f7f7f7;
-}
-
-.dkgreyback {
-background: #efefef;
-}
-
-.blueback {
-background: #e0f1ff;
-}
-
-.pinkback {
-background: #ffe0e6;
-}
-
-.yellowback {
-background: #ffffd0;
-}
-
-.blackback {
-background: #000000;
-}
-
-.purpleback {
-background: #813f62;
-}
-
-.greenback {
-background: #008000;
-}
-
-.redtext {
-color: red;
-}
-
-.whitetext {
-color: white;
-}
-
-.bluetext {
-color: #006699;
-}
-
-.centertext {
-text-align: center
-}
-
-.AZ {
- padding-right: 2px;
- padding-left: 2px;
- border: 1px solid gray;
- font-weight: bold;
- float: left;
- margin: 1px;
- width: 10px;
- text-align: center;
-}
-
-.AZselected {
- padding-right: 2px;
- padding-left: 2px;
- border: 1px solid gray;
- font-weight: bold;
- float: left;
- margin: 1px;
- text-decoration: underline;
-}
-
-/*job vacancies styles*/
-#jobvacs div {
- /*float: left;*/
- /*width: 240px;*/
- padding-right: 5px;
-}
-
-#jobvacs span {
- /*float: left;*/
-}
-
-#jobvacs div div {
- width: 100px;
- font-weight: bold;
- float: left;
-}
-
-#jobvacs br {
- /*clear: left;*/
-}
-
-/***********************************************/
-
-/*masthead*/
-#masthead {
- clear: both;
- display: block;
- height: 150px;
- width: 100%;
- border-bottom: 1px solid #fff;
- background: #013B63;
-}
-
-#bannerimage {
- height: 150px;
- background: url(http://www.scambs.gov.uk/images/southcambridgeshiredistrictcouncil/headers/defaultBg.jpg) no-repeat top left;
-}
-
-#Housingbannerimage {
- height: 150px;
- background: url(http://www.scambs.gov.uk/images/southcambridgeshiredistrictcouncil/headers/housing.jpg) no-repeat top left;
-}
-
-#homeimage {
- display: block;
- float:left;
- height: 150px;
- width:420px;
- margin: 0;
-}
-
-#homeimage img {
- display: inline;
- float:left;
-}
-
-#logo{
- display: block;
- float:right;
- height: 150px;
- margin: 0px;
- border-left: 2px solid #fff;
-}
-
-/***********************************************/
-
-/*header layer*/
-#header {
- clear: both;
- display: block;
- height: 1.9em;
- background: #427499 url(http://www.scambs.gov.uk/system/images/scambs/headerbck.jpg) repeat-y;
-}
-
-/*Header navigation*/
-#headernav {
- display: block;
- float: left;
- padding: 7px 10px 0px 15px;
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-weight: bold;
- font-size: 0.8em;
- text-align: left;
- color: #fff;
-}
-
-#headernav a:link {
- color: #fff;
-}
-
-#headernav a:visited {
- color: #fff;
-}
-#headernav a:hover {
- color: #CCCCCC;
-}
-
-#headernav a:active, #headernav a:focus {
- color: #fff;
-}
-
-/*Search navigation*/
-#headersearch {
- padding: 2px 10px 0px 5px;
- display: block;
- float: right;
- width: 300px;
- height: 27px;
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-weight: bold;
- font-size: 0.7em;
- text-align: right;
- color: #fff;
-}
-
-#headersearch a:link {
- color: #fff;
-}
-
-#headersearch a:visited {
- color: #fff;
-}
-#headersearch a:hover {
- color: #CCCCCC;
-}
-
-#headersearch a:active, #headersearch a:focus {
- color: #fff;
-}
-
-.form {
- padding: 0px 5px 0px 5px;
-}
-
-/***********************************************/
-
-
-/*Breadcrumb layer*/
-#breadcrumb {
- clear: both;
- width: 100%;
- height: 1.9em;
- margin: 0px;
- background: url(http://www.scambs.gov.uk/system/images/scambs/breadcrumb.jpg) repeat-y;
-}
-
-/*Breadcrumb navigation*/
-#breadcrumbtext {
- display: block;
- float: left;
- padding: 7px 10px 0px 15px;
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-weight: bold;
- font-size: 0.7em;
- text-align: left;
- color: #006699;
-}
-
-#breadcrumbtext a:link {
- color: #003366;
-}
-
-#breadcrumbtext a:visited {
- color: #003366;
-}
-
-#breadcrumbtext a:hover {
- color: #333;
-}
-
-#breadcrumbtext a:active, #breadcrumbtext a:focus {
- color: #fff;
-}
-
-/*************************/
-/*Content layer*/
-/* mySociety commented out
-#maintext img {
- border: 1px solid #999;
- padding: 2px;
- margin: 0px;
-}
-*/
-
-#maintext {
- display: block;
- margin: 20px 0px 0px 0px;
- padding: 5px 15px;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- line-height: 1.4em;
- font-weight: normal;
- color: #333;
- height: 100%;
-}
-
-#maintext h1 {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 1em;
- color: #003366;
- text-transform: uppercase;
- font-weight: bold;
- letter-spacing: 0.1em;
-}
-
-/*Use for subheadings*/
-#maintext h2{
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 1em;
- line-height: 1.2em;
- font-weight: bold;
- color: #006699;
-}
-
-/*Use for textheadings*/
-#maintext h3{
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.9em;
- line-height: 1em;
- color: #003366;
-}
-
-/* mySociety commented out
-#maintext ul, #maintext ol {
- margin: 0;
- padding: 0px 0px 0px 15px;
- border: none;
-}
-*/
-
-/* Style for unordered list*/
-/* mySociety commented out
-#maintext ul li {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- color: #333;
- line-height: 1.4em;
- padding: 0;
- list-style-type: disc;
-}
-*/
-
-/* Style for ordered list*/
-/* mySociety commented out
-#maintext ol li {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- color: #333;
- line-height: 1.4em;
- padding: 0;
- list-style-type: decimal;
-}
-*/
-
-#formtable img {
- border: 0px;
- padding: 5px;
-}
-
-#maintext ul.hlist, #maintext ul.hlist li {
- display: block;
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-#maintext ul.hlist li {
- float: left;
-}
-
-#maintext ul.eventdate-year, #maintext ul.eventdate-month {
- height: 30px;
-}
-
-#maintext ul.eventdate-year {
- font-size: 1em;
-}
-
-#maintext ul.eventdate-year li, #maintext ul.eventdate-month li {
- margin: 0 5px 0 0;
-}
-
-#maintext ul.eventdate-year li strong, #maintext ul.eventdate-month li strong {
- margin: 0 0 0 5px;
-}
-
-#maintext ul.eventdate-year li a, #maintext ul.eventdate-month li a {
- margin: 0 0 0 5px;
-}
-
-#maintext ul.eventdate-year li a strong, #maintext ul.eventdate-month li a strong {
- margin: 0;
-}
-
-/***********************************************/
-
-/*Content Left Column layer*/
-#left{
- float: left;
- width: 183px;
- height: 100%;
- background: url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-y right top;
-}
-
-#sectiontitle {
- display: block;
- height: 25px;
- background: #003366;
- margin-right: 1px;
-}
-
-#sectiontitle ul{
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-weight: normal;
- font-size: 0.8em;
- color: #fff;
- padding: 5px 0px 0px 15px;
- margin: 0px;
-}
-
-#sectiontitle ul li {
- list-style-type: none;
-}
-
-#sectiontitle a:link {
- color: #fff;
- text-decoration: none;
-}
-
-#sectiontitle a:visited {
- color: #fff;
- text-decoration: none;
-}
-
-#sectiontitle a:hover {
- color: #cccccc;
- text-decoration: underline;
-}
-
-#sectiontitle a:active, #sectiontitle a:focus {
- color: #fff;
-}
-
-#leftnav ul {
- margin: 0;
- padding: 0;
- border: none;
- display: block;
- clear: both;
- background: url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-x left bottom;
-}
-
-#leftnav ul li {
- list-style-type: none;
-}
-
-/*First level headings*/
-#leftnav ul li.first{
- padding: 6px 5px 10px 15px;
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-weight: bold;
- font-size: 0.8em;
- color: #003366;
- background-image: url(http://www.scambs.gov.uk/system/images/scambs/menu1_arrow.gif);
- background-repeat: no-repeat;
-}
-
-#leftnav ul li a:link {
- color: #003366;
-}
-
-#leftnav ul li a:visited {
- color: #003366;
-}
-
-#leftnav ul li a:hover {
- color: #666;
-}
-
-#leftnav ul li a:active, #leftnav ul li a:focus {
- color: #fff;
-}
-
-/*Second level headings*/
-#leftnav ul li ul.second{
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-weight: normal;
- line-height: 1.1em;
- text-align: left;
- margin: 0;
- padding: 0;
- border: none;
- color: #663300;
- background: url(http://www.scambs.gov.uk/system/images/scambs/blank.gif) repeat-x left bottom;
-}
-
-#leftnav ul li ul li
-{
- padding-right: 0px;
- padding-left: 15px;
- background-image: url(http://www.scambs.gov.uk/system/images/scambs/menu2_arrow.gif);
- padding-bottom: 0px;
- padding-top: 0px;
- background-repeat: no-repeat;
-}
-
-#leftnav ul li ul a:link {
- color: #663300;
-}
-
-#leftnav ul li ul a:visited {
- color: #663300;
-}
-
-#leftnav ul li ul a:hover {
- color: #666;
- text-decoration: underline;
-}
-
-#leftnav ul li ul a:active, #leftnav ul li ul a:focus {
- color: #fff;
-}
-
-/***********************************************/
-/*Content Middle Column layer*/
-
-#middle{
- padding: 0px 0px 30px 0px;
- /* margin: 0px 235px 0px 182px; mySociety changed */
- margin: 0 0 0 182px;
- height: 100%;
- background: #fff;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
-}
-
-#middle .padding {
- padding: 0px 10px 10px 10px;
-}
-
-#middletop h1, #middleleft h1, #middleright h1 {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- color: #003366;
- text-transform: uppercase;
- font-weight: bold;
- letter-spacing: 0.1em;
- font-size: 1em;
-}
-
-#middle a:link {
- color: #006699;
- text-decoration: none;
-}
-
-#middle a:visited {
- color: #006699;
- text-decoration: none;
-}
-
-#middle a:hover {
- color: #666;
- text-decoration: underline;
-}
-
-#middle a:active, #middle a:focus {
- color: #fff;
-}
-
-/*************************/
-/*Content Middle Top layer*/
-#middletop {
- padding-top: 22px;
- margin: 0px;
- height: 1px;
-}
-
-#middletop p {
- color: #000000;
- line-height: 1.2em;
-}
-
-#mtfeature1, #mtfeature2, #mtfeature3, #mtfeature4, .mtfeature {
- display: block;
-}
-
-#mtimage1, #mtimage2, #mtimage3, #mtimage4, .mtimage {
- display:block;
- float: left;
-}
-
-#mtimage1 img, #mtimage2 img, #mtimage3, #mtimage4 img, .mtimage img{
- border: 1px solid #999;
- padding: 2px;
- margin: 0px 10px 0px 0px;
-}
-
-#mttext1, #mttext2, #mttext3, #mttext4, .mttext {
- display: block;
-}
-
-
-#middletop h2{
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 1em;
- line-height: 1em;
- font-weight:bold;
- color: #003366;
- margin: 0px;
-}
-
-
-/*************************/
-/*Content Middle left layer*/
-
-#middleleft a:link, #middleright a:link, #middlebottom a:link {
- text-decoration: none;
-}
-
-#middleleft {
- width: 49%;
- float: left;
- padding: 10px;
- margin: 0px;
- margin-right: -10px;
- height: 1%;
-}
-
-#middleleft ul {
- margin: 0;
- padding: 0px 0px 0px 15px;
- border: none;
- clear: both;
-}
-
-#middleleft ul li{
- color: #000000;
- line-height: 1.5em;
- padding: 0px 10px 0px 0px;
- list-style-image: url(http://www.scambs.gov.uk/system/images/scambs/arrow2.gif) ;
-}
-
-
-/*************************/
-/*Content Middle right layer*/
-
-#middleright {
- margin-left: 49%;
- background: url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-y left top;
- padding: 10px;
- height: 1%;
-}
-
-#middleright ul {
- margin: 0;
- padding: 0;
- border: none;
-}
-
-#middleright ul li{
- padding: 0;
- margin: 0;
- list-style: none;
-}
-
-
-/*************************/
-/*Content Middle bottom layer*/
-
-#middlebottom, .middlebottom {
- margin-top: 10px;
- padding: 2px;
- background: url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-x;
- height: 1%;
-}
-
-/***********************************************/
-/*Content Right Column layer*/
-
-#right{
- float: right;
- width: 235px;
- background: #fff url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-y left top;
- height: 100%;
- margin: 0px;
-}
-
-.rightcontent{
- padding: 0px 3px 10px 8px;
-}
-
-.rightcontent h1 {
- color: #663300;
- font-weight: bold;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
-}
-
-#right .title {
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-size: 1em;
- color: #663300;
- text-transform: uppercase;
- font-weight: bold;
- letter-spacing: 0.1em;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
- line-height: 0.8em;
-}
-
-.rightcontent ul {
- margin: 0px;
- padding: 0px 0px 0px 17px;
- border: none;
-}
-
-.rightcontent ul li {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
- line-height: 1.5em;
- padding: 0px;
- list-style-image: url(http://www.scambs.gov.uk/system/images/scambs/arrow2.gif) ;
-}
-
-/**Right Content 1**/
-#rightcontent1, #address, div.address {
- padding: 5px 3px 10px 8px;
- background: url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-x left bottom;
-}
-
-#rightcontent1 h1, #address h1, div.address h1 {
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-size: 1em;
- color: #663300;
- text-transform: uppercase;
- font-weight: bold;
- letter-spacing: 0.1em;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
- line-height: 0.8em;
-}
-
-#rightcontent1 h2, #address h2, div.address h2{
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
- color: #333;
- margin: 0px;
- padding: 0px;
- line-height: 0.8em;
-}
-
-
-#rightcontent1 p, #address p, div.address p {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
- color: #000000;
- line-height: 1.2em;
-}
-
-
-/**Right Content 2**/
-#rightcontent2 {
- padding: 0px 3px 10px 8px;
- background: url(http://www.scambs.gov.uk/system/images/scambs/bgdots.gif) repeat-x left bottom;
-}
-#rightcontent2 h1{ font-family: "trebuchet MS", Helvetica, sans-serif;
- color: #663300;
- font-weight: bold;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
- line-height: 1em;
-}
-
-#rightcontent2 ul, #rightcontent3 ul {
- margin: 0px;
- padding: 0px 0px 0px 17px;
- border: none;
-}
-
-#rightcontent2 ul li, #rightcontent3 ul li {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
- line-height: 1.5em;
- padding: 0px;
- list-style-image: url(http://www.scambs.gov.uk/system/images/scambs/arrow2.gif) ;
-}
-
-/**Right Content 3**/
-#rightcontent3 {
- padding: 0px 3px 10px 8px;
-}
-#rightcontent3 h1{
- color: #663300;
- font-weight: bold;
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 0.7em;
-}
-
-#bottominfo {
- margin: -40px 235px 0px 200px;
- display: block;
- clear: both;
- height: 30px;
- text-align: right;
- font-size: 0.7em;
- padding: 5px;
-}
-
-#bottominfo img {
- width: 15px;
- height: 15px;
- margin-left: 5px;
-}
-
-#bottominfo ul {
- margin: 0px;
- padding: 2px;
-}
-
-#bottominfo ul li {
- list-style-type: none;
- display: inline;
-}
-
-/***********************************************/
-/*Footer layer*/
-#footer{
- display: block;
- width: 100%;
- height: 30px;
- background: #427499 url(http://www.scambs.gov.uk/system/images/scambs/headerbck.jpg) no-repeat;
-}
-
-#footertext{
- padding: 5px 0px 0px 15px;
- font-family: "trebuchet MS", Helvetica, sans-serif;
- font-weight: bold;
- font-size: 0.7em;
- text-align: left;
- color: #fff;
-}
-
-#footertext a:link {
- color: #fff;
-}
-
-#footertext a:visited {
- color: #fff;
-}
-#footertext a:hover {
- color: #CCCCCC;
-}
-
-#footertext a:active, #footertext a:focus {
- color: #fff;
-}
-
-#centrepanel img {
- border: 0px;
- padding: 0px;
-}
-
-/***********************************************/
-
-.aligncentre{
- text-align: center;
-}
diff --git a/web/faq.cgi b/web/faq.cgi deleted file mode 100755 index 4d9c7413a..000000000 --- a/web/faq.cgi +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# faq.cgi: -# FAQ page for FixMyStreet -# -# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: faq.cgi,v 1.42 2009-07-10 16:10:22 matthew Exp $ - -use strict; -use Standard -db; -use mySociety::Locale; - -my $lastmodified = (stat $0)[9]; -sub main { - my $q = shift; - print Page::header($q, title=>_('Frequently Asked Questions')); - my $lang = $mySociety::Locale::lang; - print Page::template_include("faq-$lang", $q, Page::template_root($q)); - print Page::footer($q); -} -Page::do_fastcgi(\&main, $lastmodified); - diff --git a/web/fixmystreet_app_cgi.cgi b/web/fixmystreet_app_cgi.cgi new file mode 100755 index 000000000..7d60ce673 --- /dev/null +++ b/web/fixmystreet_app_cgi.cgi @@ -0,0 +1,35 @@ +#!/usr/bin/env perl + +BEGIN { # set all the paths to the perl code + use FindBin; + require "$FindBin::Bin/../setenv.pl"; +} + +use Catalyst::ScriptRunner; +Catalyst::ScriptRunner->run( 'FixMyStreet::App', 'CGI' ); + +1; + +=head1 NAME + +fixmystreet_app_cgi.pl - Catalyst CGI + +=head1 SYNOPSIS + +See L<Catalyst::Manual> + +=head1 DESCRIPTION + +Run a Catalyst application as a cgi script. + +=head1 AUTHORS + +Catalyst Contributors, see Catalyst.pm + +=head1 COPYRIGHT + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + diff --git a/web/fixmystreet_app_fastcgi.cgi b/web/fixmystreet_app_fastcgi.cgi new file mode 100755 index 000000000..1059cbd34 --- /dev/null +++ b/web/fixmystreet_app_fastcgi.cgi @@ -0,0 +1,53 @@ +#!/usr/bin/env perl + +BEGIN { # set all the paths to the perl code + use FindBin; + require "$FindBin::Bin/../setenv.pl"; +} + +use Catalyst::ScriptRunner; +Catalyst::ScriptRunner->run( 'FixMyStreet::App', 'FastCGI' ); + +1; + +=head1 NAME + +fixmystreet_app_fastcgi.pl - Catalyst FastCGI + +=head1 SYNOPSIS + +fixmystreet_app_fastcgi.pl [options] + + Options: + -? -help display this help and exits + -l --listen Socket path to listen on + (defaults to standard input) + can be HOST:PORT, :PORT or a + filesystem path + -n --nproc specify number of processes to keep + to serve requests (defaults to 1, + requires -listen) + -p --pidfile specify filename for pid file + (requires -listen) + -d --daemon daemonize (requires -listen) + -M --manager specify alternate process manager + (FCGI::ProcManager sub-class) + or empty string to disable + -e --keeperr send error messages to STDOUT, not + to the webserver + --proc_title Set the process title (is possible) + +=head1 DESCRIPTION + +Run a Catalyst application as fastcgi. + +=head1 AUTHORS + +Catalyst Contributors, see Catalyst.pm + +=head1 COPYRIGHT + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut diff --git a/web/flickr.cgi b/web/flickr.cgi deleted file mode 100755 index 0ccce316c..000000000 --- a/web/flickr.cgi +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# flickr.cgi: -# Register for Flickr usage, and update photos -# -# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: flickr.cgi,v 1.9 2008-10-09 14:20:54 matthew Exp $ - -use strict; -use Standard; -use LWP::Simple; -use URI::Escape; -use mySociety::AuthToken; -use mySociety::Email; -use mySociety::EmailUtil; -use mySociety::Random qw(random_bytes); - -sub main { - my $q = shift; - print Page::header($q, title=>'Flickr photo upload'); - my $out = ''; - if (my $token = $q->param('token')) { - my $email = mySociety::AuthToken::retrieve('flickr', $token); - if ($email) { - my $key = mySociety::Config::get('FLICKR_API'); - my $url = 'http://api.flickr.com/services/rest/?method=flickr.people.findByEmail&api_key='.$key.'&find_email=' . uri_escape($email); - my $result = get($url); - my ($nsid) = $result =~ /nsid="([^"]*)"/; - $url = 'http://api.flickr.com/services/rest/?method=flickr.people.getInfo&api_key='.$key.'&user_id=' . uri_escape($nsid); - $result = get($url); - my ($name) = $result =~ /<realname>(.*?)<\/realname>/; - $name ||= ''; - - my $id = dbh()->selectrow_array("select nextval('partial_user_id_seq');"); - dbh()->do("insert into partial_user (id, service, nsid, name, email, phone) values (?, 'flickr', ?, ?, ?, '')", {}, - $id, $nsid, $name, $email); - dbh()->commit(); - $out .= $q->p('Thanks for confirming your email address. Please now tag -your photos with FixMyStreet (and geo-tag them if you want/can, automatically if possible!) -for us to pick them up.'); - } else { - $out = $q->p(_(<<EOF)); -Thank you for trying to register for your Flickr photos. We seem to have a -problem ourselves though, so <a href="/contact">please let us know what went on</a> -and we'll look into it. -EOF - } - } elsif (my $email = $q->param('email')) { - my $template = File::Slurp::read_file("$FindBin::Bin/../templates/emails/flickr-confirm"); - my %h = (); - my $token = mySociety::AuthToken::store('flickr', $email); - $h{url} = mySociety::Config::get('BASE_URL') . '/F/' . $token; - - my $body = mySociety::Email::construct_email({ - _template_ => $template, - _parameters_ => \%h, - To => $email, - From => [ mySociety::Config::get('CONTACT_EMAIL'), 'FixMyStreet' ], - 'Message-ID' => sprintf('<flickr-%s-%s@mysociety.org>', time(), unpack('h*', random_bytes(5, 1))), - }); - - my $result; - $result = mySociety::EmailUtil::send_email($body, mySociety::Config::get('CONTACT_EMAIL'), $email); - if ($result == mySociety::EmailUtil::EMAIL_SUCCESS) { - $out = 'Thanks, we\'ve sent you a confirmation email!'; - dbh()->commit(); - } else { - $out = 'Sorry, something went wrong - very alpha!'; - dbh()->rollback(); - } - } else { - $out .= <<EOF; -<p><strong>This feature was added for HackDay London 2007, and might not be of production quality.</strong> -Please <a href="/contact">send bug reports to us</a>.</p> -<p>Using the Flickr API, FixMyStreet can utilise all the methods of uploading photos to Flickr -to report problems to your council:</p> -<ol> -<li>Register that you're going to be using Flickr here, so we know to check your photos. -<li>Upload your photo to Flickr, for example via camera phone on location -<li>Tag the photo with FixMyStreet when uploading, or afterwards -<li>Locate the problem on Flickr's map (if you have GPS, this might be done automatically :) ) -<li>FixMyStreet will find the photo, and ask you to add/ check the details; -<li>The report is then sent to the council. -</ol> - -<form method="post"> -<p>To begin, please enter your Flickr email address, both so we know the account to watch and -so we can email you when you upload FixMyStreet photos with a link to check and confirm -the details: <input type="text" name="email" value="" size="30"> -<input type="submit" value="Go"> -</p></form> -EOF - } - - print $out; - print Page::footer($q); -} -Page::do_fastcgi(\&main); - diff --git a/web/fun.cgi b/web/fun.cgi deleted file mode 100755 index d93658dff..000000000 --- a/web/fun.cgi +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# fun.cgi: -# Weird and Wonderful -# -# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: fun.cgi,v 1.3 2008-09-19 10:24:55 matthew Exp $ - -use strict; -use Standard -db; - -# Main code for index.cgi -sub main { - my $q = shift; - print Page::header($q, title=>_('Weird and Wonderful reports')); - print fun($q); - print Page::footer($q); -} -Page::do_fastcgi(\&main); - -sub fun { - my $q = shift; - my $out = $q->h1(_('Weird and Wonderful reports')); - $out .= $q->p('Here are some of the best or strangest reports we’ve seen on FixMyStreet. -They’ve all been fixed, and in one case could have saved lives! -Do let us know if you find any more.'); - $out .= $q->ul({style => 'list-style-type: none; margin:0; padding:0'}, - $q->li( - $q->img({src=>'http://www.fixmystreet.com/photo?id=9468', align=>'right', hspace=>8}), - $q->h2('Dumped Piano (right)'), - $q->p('The reporter of this problem summed it up with their report, -which consisted solely of the one character “!”. —', -$q->a({href=>'http://www.fixmystreet.com/report/9468'}, 'Problem report')), - ), - $q->li( - $q->h2('Mad Seagull'), - $q->p('“A seagull is attacking various cars within this road. He starts at around 05:45 every morning and continues until around 19:30. This causes a lot of noisy banging and wakes up children.” —', -$q->a({href=>'http://www.fixmystreet.com/report/2722'}, 'Problem report')), - ), - $q->li( - $q->img({src=>'http://www.fixmystreet.com/photo?id=6553', align=>'right', hspace=>8}), - $q->h2('Boxes full of cheese dumped (right)'), - $q->p('“About a dozen boxes full of mozzarella cheese have been dumped opposite 3 rufford street. if it warms up we could have nasty road topping problem (seriously there is a lot of cheese)” —', -$q->a({href=>'http://www.fixmystreet.com/report/6553'}, 'Problem report')), - ), - $q->li( - $q->h2('Dangerous Nivea Billboard'), - $q->p('“The Nivea \'Oxygen is a wonderful thing\' billboard here has a device on it releasing bubbles and foam. This is blowing into the road which is both distracting and dangerous to drivers. A large ball of foam hit my windscreen unexpectedly and nearly caused me to have an accident” —', -$q->a({href=>'http://www.fixmystreet.com/report/7552'}, 'Problem report')), - ), - ); - return $out; -} - diff --git a/web/import.cgi b/web/import.cgi deleted file mode 100755 index 76ac61841..000000000 --- a/web/import.cgi +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# import.cgi -# Script to which things like iPhones can POST new data -# -# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: import.cgi,v 1.11 2009-12-10 16:22:49 matthew Exp $ - -use strict; -use Error qw(:try); -use Standard; -use Utils; -use mySociety::AuthToken; -use mySociety::Config; -use mySociety::EmailUtil; - -sub main { - my $q = shift; - - my @vars = qw(service subject detail name email phone easting northing lat lon id phone_id); - my %input = map { $_ => $q->param($_) || '' } @vars; - my @errors; - - unless ($ENV{REQUEST_METHOD} eq 'POST') { - print Page::header($q, title=>'External import'); - docs(); - print Page::footer($q); - return; - } - - # If we were given easting, northing convert to lat lon now - my $latitude = $input{lat} ||= 0; - my $longitude = $input{lon} ||= 0; - if ( - !( $latitude || $longitude ) # have not been given lat or lon - && ( $input{easting} && $input{northing} ) # but do have e and n - ) - { - ( $latitude, $longitude ) = - Utils::convert_en_to_latlon( $input{easting}, $input{northing}); - } - - my $fh = $q->upload('photo'); # MUST come before $q->header, don't know why! - print $q->header(-charset => 'utf-8', -content_type => 'text/plain'); - - if ($fh) { - my $err = Page::check_photo($q, $fh); - push @errors, $err if $err; - } - - push @errors, 'You must supply a service' unless $input{service}; - push @errors, 'Please enter a subject' unless $input{subject} && $input{subject} =~ /\S/; - push @errors, 'Please enter your name' unless $input{name} && $input{name} =~ /\S/; - - if (!$input{email} || $input{email} !~ /\S/) { - push @errors, 'Please enter your email'; - } elsif (!mySociety::EmailUtil::is_valid_email($input{email})) { - push @errors, 'Please enter a valid email'; - } - - if ( $latitude && mySociety::Config::get('COUNTRY') eq 'GB' ) { - try { - Utils::convert_latlon_to_en( $latitude, $longitude ); - } catch Error::Simple with { - my $e = shift; - push @errors, "We had a problem with the supplied co-ordinates - outside the UK?"; - }; - } - - # TODO: Get location from photo if present in EXIF data? - - my $photo; - if ($fh) { - try { - $photo = Page::process_photo($fh, 1); - } catch Error::Simple with { - my $e = shift; - push @errors, "That photo doesn't appear to have uploaded correctly ($e), please try again."; - }; - } - - unless ( $photo || ( $latitude || $longitude ) ) { - push @errors, 'Either a location or a photo must be provided.'; - } - - if (@errors) { - print map { "ERROR:$_\n" } @errors; - return; - } - - # Store for possible future use - if ($input{id} || $input{phone_id}) { - my $id = $input{id} || $input{phone_id}; - my $already = dbh()->selectrow_array('select id from partial_user where service=? and nsid=?', {}, $input{service}, $id); - unless ($already) { - dbh()->do('insert into partial_user (service, nsid, name, email, phone) values (?, ?, ?, ?, ?)', - {}, $input{service}, $id, $input{name}, $input{email}, $input{phone}); - } - } - - # Store what we have so far in the database - my $id = dbh()->selectrow_array("select nextval('problem_id_seq')"); - Utils::workaround_pg_bytea("insert into problem - (id, postcode, latitude, longitude, title, detail, name, service, - email, phone, photo, state, used_map, anonymous, category, areas) - values - (?, '', ?, ?, ?, ?, ?, ?, ?, ?, ?, 'partial', 't', 'f', '', '')", 10, - $id, $latitude, $longitude, $input{subject}, - $input{detail}, $input{name}, $input{service}, $input{email}, $input{phone}, $photo); - - my $token = mySociety::AuthToken::store('partial', $id); - my %h = ( - name => $input{name} ? ' ' . $input{name} : '', - url => Page::base_url_with_lang($q, undef, 1) . '/L/' . $token, - service => $input{service}, - title => $input{title}, - detail => $input{detail}, - ); - - Page::send_email($q, $input{email}, $input{name}, 'partial', %h); - - dbh()->commit(); - print 'SUCCESS'; -} - -Page::do_fastcgi(\&main); - -sub docs { - my $base = mySociety::Config::get('BASE_URL'); - print <<EOF; -<p>You may inject problem reports into FixMyStreet programatically using this -simple interface. Upon receipt, an email will be sent to the address given, -with a link the user must click in order to check the details of their report, -add any other information they wish, and then submit to the council. - -<p>This interface returns a plain text response; either <samp>SUCCESS</samp> if -the report has been successfully received, or if not, a list of errors, one per -line each starting with <samp>ERROR:</samp>. - -<p>You may submit the following information by POST to this URL -(i.e. <samp>$base/import</samp> ):</p> -<dl> -<dt>service -<dd> -<em>Required</em>. -Name of application/service using this interface. -<dt>id -<dd>Unique ID of a user/device, for possible future use. -<br><small>(e.g. used by Flickr import to know which accounts to look at)</small> -<dt>subject -<dd> -<em>Required</em>. Subject of problem report. -<dt>detail -<dd>Main body and details of problem report. -<dt>name -<dd> -<em>Required</em>. Name of problem reporter. -<dt>email -<dd> -<em>Required</em>. Email address of problem reporter. -<dt>phone -<dd>Telephone number of problem reporter. -<dt>easting / northing -<dt>lat / lon -<dd>Location of problem report. You can either supply eastings/northings, or WGS84 latitude/longitude. -<dt>photo -<dd>Photo of problem (JPEG only). -</dl> -EOF -} - diff --git a/web/index.cgi b/web/index.cgi deleted file mode 100755 index ef4b3eee1..000000000 --- a/web/index.cgi +++ /dev/null @@ -1,1163 +0,0 @@ -#!/usr/bin/perl -w -I../perllib -# -# index.cgi: -# Main code for FixMyStreet -# -# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org - -use strict; -use Standard; -use Utils; -use Encode; -use Error qw(:try); -use File::Slurp; -use CGI::Carp; -use POSIX qw(strcoll); -use URI::Escape; - -# use Carp::Always; - -use CrossSell; -use FixMyStreet::Geocode; -use mySociety::AuthToken; -use mySociety::Config; -use mySociety::DBHandle qw(select_all); -use mySociety::EmailUtil; -use mySociety::Locale; -use mySociety::MaPit; -use mySociety::PostcodeUtil; -use mySociety::Random; -use mySociety::VotingArea; -use mySociety::Web qw(ent NewURL); -use Utils; - -sub debug (@) { - return; - my ( $format, @args ) = @_; - warn sprintf $format, map { defined $_ ? $_ : 'undef' } @args; -} - -BEGIN { - if (!dbh()->selectrow_array('select secret from secret for update of secret')) { - local dbh()->{HandleError}; - dbh()->do('insert into secret (secret) values (?)', {}, unpack('h*', mySociety::Random::random_bytes(32))); - } - dbh()->commit(); -} - -# Main code for index.cgi -sub main { - my $q = shift; - - if (my $partial = $q->param('partial_token')) { - # We have a partial token, so fetch data from database and see where we're at. - my $id = mySociety::AuthToken::retrieve('partial', $partial); - if ($id) { - my @row = dbh()->selectrow_array( - "select latitude, longitude, name, email, title, (photo is not null) as has_photo, phone, detail - from problem where id=? and state='partial'", {}, $id); - if (@row) { - $q->param('anonymous', 1); - $q->param('submit_map', 1); - $q->param('latitude', $row[0]); - $q->param('longitude', $row[1]); - $q->param('name', $row[2]); - $q->param('email', $row[3]); - $q->param('title', $row[4]); - $q->param('has_photo', $row[5]); - $q->param('phone', $row[6]); - $q->param('detail', $row[7]); - $q->param('partial', $partial); - } else { - my $base = mySociety::Config::get('BASE_URL'); - print $q->redirect(-location => $base . '/report/' . $id); - } - } - } - - my $out = ''; - my %params; - if ($q->param('submit_problem')) { - $params{title} = _('Submitting your report'); - ($out, %params) = submit_problem($q); - } elsif ($q->param('submit_update')) { - $params{title} = _('Submitting your update'); - ($out, %params) = submit_update($q); - } elsif ($q->param('submit_map')) { - ($out, %params) = display_form($q, [], {}); - $params{title} = _('Reporting a problem'); - } elsif ($q->param('id')) { - ($out, %params) = display_problem($q, [], {}); - $params{title} .= ' - ' . _('Viewing a problem'); - } elsif ($q->param('pc') || ($q->param('x') && $q->param('y')) || ($q->param('lat') || $q->param('lon'))) { - ($out, %params) = display_location($q); - $params{title} = _('Viewing a location'); - } elsif ($q->param('e') && $q->param('n')) { - ($out, %params) = redirect_from_osgb_to_wgs84($q); - } else { - ($out, %params) = front_page($q); - } - print Page::header($q, %params); - print $out; - my %footerparams; - $footerparams{js} = $params{js} if $params{js}; - $footerparams{template} = $params{template} if $params{template}; - print Page::footer($q, %footerparams); -} -Page::do_fastcgi(\&main); - -# Display front page -sub front_page { - my ($q, $error, $status_code) = @_; - my $pc_h = ent($q->param('pc') || ''); - - # Look up various cobrand things - my $cobrand = Page::get_cobrand($q); - my $cobrand_form_elements = Cobrand::form_elements($cobrand, 'postcodeForm', $q); - my $form_action = Cobrand::url($cobrand, '/', $q); - my $question = Cobrand::enter_postcode_text($cobrand, $q); - $question = _("Enter a nearby GB postcode, or street name and area") - unless $question; - my %params = ('context' => 'front-page'); - $params{status_code} = $status_code if $status_code; - my %vars = ( - error => $error || '', - pc_h => $pc_h, - cobrand_form_elements => $cobrand_form_elements, - form_action => $form_action, - question => "$question:", - ); - my $cobrand_front_page = Page::template_include('front-page', $q, Page::template_root($q), %vars); - return ($cobrand_front_page, %params) if $cobrand_front_page; - - my $out = '<p id="expl"><strong>' . _('Report, view, or discuss local problems') . '</strong>'; - my $subhead = _('(like graffiti, fly tipping, broken paving slabs, or street lighting)'); - $subhead = '(like graffiti, fly tipping, or broken paving slabs)' - if $q->{site} eq 'southampton'; - $out .= '<br><small>' . $subhead . '</small>' if $subhead ne ' '; - $out .= '</p>'; - #if (my $url = mySociety::Config::get('IPHONE_URL')) { - # my $getiphone = _("Get FixMyStreet on your iPhone"); - # my $new = _("New!"); - # if ($q->{site} eq 'fixmystreet') { - # $out .= <<EOF -#<p align="center" style="margin-bottom:0"> -#<img width="23" height="12" alt="$new" src="/i/new.png" border="0"> -#<a href="$url">$getiphone</a> -#</p> -#EOF - # } - #} - $out .= '<p class="error">' . $error . '</p>' if ($error); - - # Add pretty commas for display - $out .= '<form action="' . $form_action . '" method="get" name="postcodeForm" id="postcodeForm">'; - if (my $token = $q->param('partial')) { - my $id = mySociety::AuthToken::retrieve('partial', $token); - if ($id) { - my $thanks = _("Thanks for uploading your photo. We now need to locate your problem, so please enter a nearby street name or postcode in the box below :"); - $out .= <<EOF; -<p style="margin-top: 0; color: #cc0000;"><img align="right" src="/photo?id=$id" hspace="5">$thanks</p> - -<input type="hidden" name="partial_token" value="$token"> -EOF - } - } - my $activate = _("Go"); - $out .= <<EOF; -<label for="pc">$question:</label> - <input type="text" name="pc" value="$pc_h" id="pc" size="10" maxlength="200"> - <input type="submit" value="$activate" id="submit"> -$cobrand_form_elements -</form> - -<div id="front_intro"> -EOF - $out .= $q->h2(_('How to report a problem')); - $out .= $q->ol( - $q->li($question), - $q->li(_('Locate the problem on a map of the area')), - $q->li(_('Enter details of the problem')), - $q->li(_('We send it to the council on your behalf')) - ); - - - $out .= Cobrand::front_stats(Page::get_cobrand($q), $q); - - $out .= <<EOF; -</div> - -EOF - - my $recent_photos = Cobrand::recent_photos(Page::get_cobrand($q), 3); - my $probs = Cobrand::recent(Page::get_cobrand($q)); - if (@$probs || $recent_photos){ - $out .= '<div id="front_recent">'; - $out .= $q->h2(_('Photos of recent reports')) . $recent_photos if $recent_photos; - - $out .= $q->h2(_('Recently reported problems')) . ' <ul>' if @$probs; - foreach (@$probs) { - $out .= '<li><a href="/report/' . $_->{id} . '">'. ent($_->{title}); - $out .= '</a></li>'; - } - $out .= '</ul>' if @$probs; - $out .= '</div>'; - } - - if ($q->{site} eq 'emptyhomes') { - $out .= <<EOF; -<div id="eha_advert"> -Now is the best time to turn empty properties into empty homes... Don't miss it! -<a href="http://www.emptyhomes.com/EHConference2011.html">Home Again: Empty Homes National Conference 2011</a> -</div> -EOF - } - - return ($out, %params); -} - -sub submit_update { - my $q = shift; - my @vars = qw(id name rznvy update fixed upload_fileid add_alert); - my %input = map { $_ => $q->param($_) || '' } @vars; - my @errors; - my %field_errors; - - my $fh = $q->upload('photo'); - if ($fh) { - my $err = Page::check_photo($q, $fh); - push @errors, $err if $err; - } - $field_errors{update} = _('Please enter a message') unless $input{update} =~ /\S/; - $input{name} = undef unless $input{name} =~ /\S/; - if ($input{rznvy} !~ /\S/) { - $field_errors{email} = _('Please enter your email'); - } elsif (!mySociety::EmailUtil::is_valid_email($input{rznvy})) { - $field_errors{email} = _('Please enter a valid email'); - } - - my $image; - if ($fh) { - try { - $image = Page::process_photo($fh); - } catch Error::Simple with { - my $e = shift; - push(@errors, sprintf(_("That image doesn't appear to have uploaded correctly (%s), please try again."), $e)); - }; - } - - if ($input{upload_fileid}) { - open FP, mySociety::Config::get('UPLOAD_CACHE') . $input{upload_fileid}; - $image = join('', <FP>); - close FP; - } - - return display_problem($q, \@errors, \%field_errors) if (@errors || scalar(keys(%field_errors))); - my $cobrand = Page::get_cobrand($q); - my $cobrand_data = Cobrand::extra_update_data($cobrand, $q); - my $id = dbh()->selectrow_array("select nextval('comment_id_seq');"); - Utils::workaround_pg_bytea("insert into comment - (id, problem_id, name, email, website, text, state, mark_fixed, photo, lang, cobrand, cobrand_data) - values (?, ?, ?, ?, '', ?, 'unconfirmed', ?, ?, ?, ?, ?)", 7, - $id, $input{id}, $input{name}, $input{rznvy}, $input{update}, - $input{fixed} ? 't' : 'f', $image, $mySociety::Locale::lang, $cobrand, $cobrand_data); - - my %h = (); - $h{update} = $input{update}; - $h{name} = $input{name} ? $input{name} : _("Anonymous"); - my $base = Page::base_url_with_lang($q, undef, 1); - $h{url} = $base . '/C/' . mySociety::AuthToken::store('update', { id => $id, add_alert => $input{add_alert} } ); - dbh()->commit(); - - my $out = Page::send_confirmation_email($q, $input{rznvy}, $input{name}, 'update', %h); - return $out; -} - -sub submit_problem { - my $q = shift; - my @vars = qw(council title detail name email phone pc skipped anonymous category partial upload_fileid latitude longitude); - my %input = map { $_ => scalar $q->param($_) } @vars; - for (qw(title detail)) { - $input{$_} = lc $input{$_} if $input{$_} !~ /[a-z]/; - $input{$_} = ucfirst $input{$_}; - $input{$_} =~ s/\b(dog\s*)shit\b/$1poo/ig; - $input{$_} =~ s/\b(porta)\s*([ck]abin|loo)\b/[$1ble $2]/ig; - $input{$_} =~ s/kabin\]/cabin\]/ig; - } - my @errors; - my %field_errors; - - my $cobrand = Page::get_cobrand($q); - - # If in UK and we have a lat,lon coocdinate check it is in UK - if ( $input{latitude} && mySociety::Config::get('COUNTRY') eq 'GB' ) { - try { - Utils::convert_latlon_to_en( $input{latitude}, $input{longitude} ); - } catch Error::Simple with { - my $e = shift; - push @errors, "We had a problem with the supplied co-ordinates - outside the UK?"; - }; - } - - my $fh = $q->upload('photo'); - if ($fh) { - my $err = Page::check_photo($q, $fh); - $field_errors{photo} = $err if $err; - } - - $input{council} = 2260 if $q->{site} eq 'scambs'; # All reports go to S. Cambs - push(@errors, _('No council selected')) unless ($input{council} && $input{council} =~ /^(?:-1|[\d,]+(?:\|[\d,]+)?)$/); - $field_errors{title} = _('Please enter a subject') unless $input{title} =~ /\S/; - $field_errors{detail} = _('Please enter some details') unless $input{detail} =~ /\S/; - if ($input{name} !~ /\S/) { - $field_errors{name} = _('Please enter your name'); - } elsif (length($input{name}) < 5 || $input{name} !~ /\s/ || $input{name} =~ /\ba\s*n+on+((y|o)mo?u?s)?(ly)?\b/i) { - $field_errors{name} = _('Please enter your full name, councils need this information - if you do not wish your name to be shown on the site, untick the box'); - } - if ($input{email} !~ /\S/) { - $field_errors{email} = _('Please enter your email'); - } elsif (!mySociety::EmailUtil::is_valid_email($input{email})) { - $field_errors{email} = _('Please enter a valid email'); - } - if ($input{category} && $input{category} eq _('-- Pick a category --')) { - $field_errors{category} = _('Please choose a category'); - $input{category} = ''; - } elsif ($input{category} && $input{category} eq _('-- Pick a property type --')) { - $field_errors{category} = _('Please choose a property type'); - $input{category} = ''; - } - - return display_form($q, \@errors, \%field_errors) if (@errors || scalar keys %field_errors); # Short circuit - - my $areas; - if (defined $input{latitude} && defined $input{longitude}) { - my $mapit_query = "4326/$input{longitude},$input{latitude}"; - $areas = mySociety::MaPit::call( 'point', $mapit_query ); - if ($input{council} =~ /^[\d,]+(\|[\d,]+)?$/) { - my $no_details = $1 || ''; - my @area_types = Cobrand::area_types($cobrand); - my %va = map { $_ => 1 } @area_types; - my %councils; - my $london = 0; - foreach (keys %$areas) { - $councils{$_} = 1 if $va{$areas->{$_}->{type}}; - $london = 1 if $areas->{$_}->{type} eq 'LBO' && $q->{site} ne 'emptyhomes'; - } - my @input_councils = split /,|\|/, $input{council}; - foreach (@input_councils) { - if (!$councils{$_}) { - push(@errors, _('That location is not part of that council')); - last; - } - } - - if ($no_details) { - $input{council} =~ s/\Q$no_details\E//; - @input_councils = split(/,/, $input{council}); - } - - # Check category here, won't be present if council is -1 - my @valid_councils = @input_councils; - if ($london) { - $field_errors{category} = _('Please choose a category') - unless Utils::london_categories()->{$input{category}}; - @valid_councils = $input{council}; - } elsif ($input{category} && $q->{site} ne 'emptyhomes') { - my $categories = select_all("select area_id from contacts - where deleted='f' and area_id in (" - . $input{council} . ') and category = ?', $input{category}); - $field_errors{category} = _('Please choose a category') unless @$categories; - @valid_councils = map { $_->{area_id} } @$categories; - foreach my $c (@valid_councils) { - if ($no_details =~ /$c/) { - push(@errors, _('We have details for that council')); - $no_details =~ s/,?$c//; - } - } - } - $input{council} = join(',', @valid_councils) . $no_details; - } - $areas = ',' . join(',', sort keys %$areas) . ','; - } elsif (defined $input{latitude} || defined $input{longitude}) { - push(@errors, _('Somehow, you only have one co-ordinate. Please try again.')); - } else { - push(@errors, _("You haven't specified any sort of co-ordinates. Please try again.")); - } - - my $image; - if ($fh) { - try { - $image = Page::process_photo($fh); - } catch Error::Simple with { - my $e = shift; - $field_errors{photo} = sprintf(_("That image doesn't appear to have uploaded correctly (%s), please try again."), $e); - }; - } - - if ($input{upload_fileid}) { - open FP, mySociety::Config::get('UPLOAD_CACHE') . $input{upload_fileid}; - $image = join('', <FP>); - close FP; - } - - return display_form($q, \@errors, \%field_errors) if (@errors || scalar keys %field_errors); - - delete $input{council} if $input{council} eq '-1'; - my $used_map = $input{skipped} ? 'f' : 't'; - $input{category} = _('Other') unless $input{category}; - my ($id, $out); - my $cobrand_data = Cobrand::extra_problem_data($cobrand, $q); - if (my $token = $input{partial}) { - my $id = mySociety::AuthToken::retrieve('partial', $token); - if ($id) { - dbh()->do("update problem set postcode=?, latitude=?, longitude=?, title=?, detail=?, - name=?, email=?, phone=?, state='confirmed', council=?, used_map='t', - anonymous=?, category=?, areas=?, cobrand=?, cobrand_data=?, confirmed=ms_current_timestamp(), - lastupdate=ms_current_timestamp() where id=?", {}, $input{pc}, $input{latitude}, $input{longitude}, - $input{title}, $input{detail}, $input{name}, $input{email}, - $input{phone}, $input{council}, $input{anonymous} ? 'f' : 't', - $input{category}, $areas, $cobrand, $cobrand_data, $id); - Utils::workaround_pg_bytea('update problem set photo=? where id=?', 1, $image, $id) - if $image; - dbh()->commit(); - $out = $q->p(sprintf(_('You have successfully confirmed your report and you can now <a href="%s">view it on the site</a>.'), "/report/$id")); - my $display_advert = Cobrand::allow_crosssell_adverts($cobrand); - if ($display_advert) { - $out .= CrossSell::display_advert($q, $input{email}, $input{name}); - } - } else { - $out = $q->p('There appears to have been a problem updating the details of your report. -Please <a href="/contact">let us know what went on</a> and we\'ll look into it.'); - } - } else { - $id = dbh()->selectrow_array("select nextval('problem_id_seq');"); - Utils::workaround_pg_bytea("insert into problem - (id, postcode, latitude, longitude, title, detail, name, - email, phone, photo, state, council, used_map, anonymous, category, areas, lang, cobrand, cobrand_data) - values - (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'unconfirmed', ?, ?, ?, ?, ?, ?, ?, ?)", 10, - $id, $input{pc}, $input{latitude}, $input{longitude}, $input{title}, - $input{detail}, $input{name}, $input{email}, $input{phone}, $image, - $input{council}, $used_map, $input{anonymous} ? 'f': 't', $input{category}, - $areas, $mySociety::Locale::lang, $cobrand, $cobrand_data); - my %h = (); - $h{title} = $input{title}; - $h{detail} = $input{detail}; - $h{name} = $input{name}; - my $base = Page::base_url_with_lang($q, undef, 1); - $h{url} = $base . '/P/' . mySociety::AuthToken::store('problem', $id); - dbh()->commit(); - - $out = Page::send_confirmation_email($q, $input{email}, $input{name}, 'problem', %h); - - } - return $out; -} - -sub display_form { - my ($q, $errors, $field_errors) = @_; - my @errors = @$errors; - my %field_errors = %{$field_errors}; - my $cobrand = Page::get_cobrand($q); - push @errors, _('There were problems with your report. Please see below.') if (scalar keys %field_errors); - - my ($pin_x, $pin_y, $pin_tile_x, $pin_tile_y) = (0,0,0,0); - my @vars = qw(title detail name email phone pc latitude longitude x y skipped council anonymous partial upload_fileid); - - my %input = (); - my %input_h = (); - - foreach my $key (@vars) { - my $val = $q->param($key); - $input{$key} = defined($val) ? $val : ''; # '0' is valid for longitude - $input_h{$key} = ent( $input{$key} ); - } - - # Convert lat/lon to easting/northing if given - # if ($input{lat}) { - # try { - # ($input{easting}, $input{northing}) = mySociety::GeoUtil::wgs84_to_national_grid($input{lat}, $input{lon}, 'G'); - # $input_h{easting} = $input{easting}; - # $input_h{northing} = $input{northing}; - # } catch Error::Simple with { - # my $e = shift; - # push @errors, "We had a problem with the supplied co-ordinates - outside the UK?"; - # }; - # } - - # Get tile co-ordinates if map clicked - ($input{x}) = $input{x} =~ /^(\d+)/; $input{x} ||= 0; - ($input{y}) = $input{y} =~ /^(\d+)/; $input{y} ||= 0; - my @ps = $q->param; - foreach (@ps) { - ($pin_tile_x, $pin_tile_y, $pin_x) = ($1, $2, $q->param($_)) if /^tile_(\d+)\.(\d+)\.x$/; - $pin_y = $q->param($_) if /\.y$/; - } - - # We need either a map click, an E/N, to be skipping the map, or be filling in a partial form - return display_location($q, @errors) - unless ($pin_x && $pin_y) - || ($input{latitude} && $input{longitude}) - || ($input{skipped} && $input{pc}) - || ($input{partial} && $input{pc}); - - # Work out some co-ordinates from whatever we've got - my ($latitude, $longitude); - if ($input{skipped}) { - # Map is being skipped - if ( length $input{latitude} && length $input{longitude} ) { - $latitude = $input{latitude}; - $longitude = $input{longitude}; - } else { - my ( $lat, $lon, $error ) = - FixMyStreet::Geocode::lookup( $input{pc}, $q ); - $latitude = $lat; - $longitude = $lon; - } - } elsif ($pin_x && $pin_y) { - - # Map was clicked on (tilma, or non-JS OpenLayers, for example) - ($latitude, $longitude) = FixMyStreet::Map::click_to_wgs84($q, $pin_tile_x, $pin_x, $pin_tile_y, $pin_y); - - } elsif ( $input{partial} && $input{pc} && !length $input{latitude} && !length $input{longitude} ) { - my $error; - try { - ($latitude, $longitude, $error) = FixMyStreet::Geocode::lookup($input{pc}, $q); - } catch Error::Simple with { - $error = shift; - }; - return FixMyStreet::Geocode::list_choices($error, '/', $q) if ref($error) eq 'ARRAY'; - return front_page($q, $error) if $error; - } else { - # Normal form submission - $latitude = $input_h{latitude}; - $longitude = $input_h{longitude}; - } - - # Shrink, as don't need accuracy plus we want them as English strings - ($latitude, $longitude) = map { Utils::truncate_coordinate($_) } ( $latitude, $longitude ); - - # Look up councils and do checks for the point we've got - my @area_types = Cobrand::area_types($cobrand); - # XXX: I think we want in_gb_locale around the next line, needs testing - my $all_councils = mySociety::MaPit::call('point', "4326/$longitude,$latitude", type => \@area_types); - - # Let cobrand do a check - my ($success, $error_msg) = Cobrand::council_check($cobrand, { all_councils => $all_councils }, $q, 'submit_problem'); - if (!$success) { - return front_page($q, $error_msg); - } - - if (mySociety::Config::get('COUNTRY') eq 'GB') { - # Ipswich & St Edmundsbury are responsible for everything in their areas, not Suffolk - delete $all_councils->{2241} if $all_councils->{2446} || $all_councils->{2443}; - - # Norwich is responsible for everything in its areas, not Norfolk - delete $all_councils->{2233} if $all_councils->{2391}; - - } elsif (mySociety::Config::get('COUNTRY') eq 'NO') { - - # Oslo is both a kommune and a fylke, we only want to show it once - delete $all_councils->{301} if $all_councils->{3}; - - } - - return display_location($q, _('That spot does not appear to be covered by a council. -If you have tried to report an issue past the shoreline, for example, -please specify the closest point on land.')) unless %$all_councils; - - # Look up categories for this council or councils - my $category = ''; - my (%council_ok, @categories); - my $categories = select_all("select area_id, category from contacts - where deleted='f' and area_id in (" . join(',', keys %$all_councils) . ')'); - my $first_council = (values %$all_councils)[0]; - if ($q->{site} eq 'emptyhomes') { - foreach (@$categories) { - $council_ok{$_->{area_id}} = 1; - } - @categories = (_('-- Pick a property type --'), _('Empty house or bungalow'), - _('Empty flat or maisonette'), _('Whole block of empty flats'), - _('Empty office or other commercial'), _('Empty pub or bar'), - _('Empty public building - school, hospital, etc.')); - $category = _('Property type:'); - } elsif ($first_council->{type} eq 'LBO') { - $council_ok{$first_council->{id}} = 1; - @categories = (_('-- Pick a category --'), sort keys %{ Utils::london_categories() } ); - $category = _('Category:'); - } else { - @$categories = sort { strcoll($a->{category}, $b->{category}) } @$categories; - my %seen; - foreach (@$categories) { - $council_ok{$_->{area_id}} = 1; - next if $_->{category} eq _('Other'); - next if $q->{site} eq 'southampton' && $_->{category} eq 'Street lighting'; - push @categories, $_->{category} unless $seen{$_->{category}}; - $seen{$_->{category}} = 1; - } - if ($q->{site} eq 'scambs') { - @categories = Page::scambs_categories(); - } - if (@categories) { - @categories = (_('-- Pick a category --'), @categories, _('Other')); - $category = _('Category:'); - } - } - $category = $q->label({'for'=>'form_category'}, $category) . - $q->popup_menu(-name=>'category', -values=>\@categories, -id=>'form_category', - -attributes=>{id=>'form_category'}) - if $category; - - # Work out what help text to show, depending on whether we have council details - my @councils = keys %council_ok; - my $details; - if (@councils == scalar keys %$all_councils) { - $details = 'all'; - } elsif (@councils == 0) { - $details = 'none'; - } else { - $details = 'some'; - } - - # Forms that allow photos need a different enctype - my $allow_photo_upload = Cobrand::allow_photo_upload($cobrand); - my $enctype = ''; - if ($allow_photo_upload) { - $enctype = ' enctype="multipart/form-data"'; - } - - my %vars; - $vars{input_h} = \%input_h; - $vars{field_errors} = \%field_errors; - if ($input{skipped}) { - my $cobrand_form_elements = Cobrand::form_elements($cobrand, 'mapSkippedForm', $q); - my $form_action = Cobrand::url($cobrand, '/', $q); - $vars{form_start} = <<EOF; -<form action="$form_action" method="post" name="mapSkippedForm"$enctype> -<input type="hidden" name="latitude" value="$latitude"> -<input type="hidden" name="longitude" value="$longitude"> -<input type="hidden" name="pc" value="$input_h{pc}"> -<input type="hidden" name="skipped" value="1"> -$cobrand_form_elements -<div id="skipped-map"> -EOF - } else { - my $type; - if ($allow_photo_upload) { - $type = 2; - } else { - $type = 1; - } - $vars{form_start} = FixMyStreet::Map::display_map($q, - latitude => $latitude, longitude => $longitude, - type => $type, - pins => [ [ $latitude, $longitude, 'purple' ] ], - ); - my $partial_id; - if (my $token = $input{partial}) { - $partial_id = mySociety::AuthToken::retrieve('partial', $token); - if ($partial_id) { - $vars{form_start} .= - $q->p({ id => 'unknown' }, - _('Please note your report has <strong>not yet been sent</strong>. Choose a category and add further information below, then submit.')); - } - } - $vars{text_located} = $q->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. ')); - } - $vars{page_heading} = $q->h1(_('Reporting a problem')); - - if ($details eq 'all') { - my $council_list = join('</strong>' . _(' or ') . '<strong>', map { $_->{name} } values %$all_councils); - if ($q->{site} eq 'emptyhomes') { - $vars{text_help} = '<p>' . sprintf(_('All the information you provide here will be sent to <strong>%s</strong>. -On the site, we will show the subject and details of the problem, plus your -name if you give us permission.'), $council_list); - } elsif ($first_council->{type} eq 'LBO') { - $vars{text_help} = '<p>' . sprintf(_('All the information you - provide here will be sent to <strong>%s</strong> or a relevant - local body such as TfL, via the London Report-It system. The - subject and details of the problem will be public, plus your name - if you give us permission.'), $council_list); - } else { - $vars{text_help} = '<p>' . sprintf(_('All the information you provide here will be sent to <strong>%s</strong>. -The subject and details of the problem will be public, plus your -name if you give us permission.'), $council_list); - } - $vars{text_help} .= '<input type="hidden" name="council" value="' . join(',', keys %$all_councils) . '">'; - } elsif ($details eq 'some') { - my $e = Cobrand::contact_email($cobrand); - my %councils = map { $_ => 1 } @councils; - my @missing; - foreach (keys %$all_councils) { - push @missing, $_ unless $councils{$_}; - } - my $n = @missing; - my $list = join(_(' or '), map { $all_councils->{$_}->{name} } @missing); - $vars{text_help} = '<p>' . _('All the information you provide here will be sent to') . ' <strong>' - . join('</strong>' . _(' or ') . '<strong>', map { $all_councils->{$_}->{name} } @councils) - . '</strong>. '; - $vars{text_help} .= _('The subject and details of the problem will be public, plus your name if you give us permission.'); - $vars{text_help} .= ' ' . mySociety::Locale::nget( - 'We do <strong>not</strong> yet have details for the other council that covers this location.', - 'We do <strong>not</strong> yet have details for the other councils that cover this location.', - $n - ); - $vars{text_help} .= ' ' . sprintf(_("You can help us by finding a contact email address for local problems for %s and emailing it to us at <a href='mailto:%s'>%s</a>."), $list, $e, $e); - $vars{text_help} .= '<input type="hidden" name="council" value="' . join(',', @councils) - . '|' . join(',', @missing) . '">'; - } else { - my $e = Cobrand::contact_email($cobrand); - my $list = join(_(' or '), map { $_->{name} } values %$all_councils); - my $n = scalar keys %$all_councils; - if ($q->{site} ne 'emptyhomes') { - $vars{text_help} = '<p>'; - $vars{text_help} .= mySociety::Locale::nget( - 'We do not yet have details for the council that covers this location.', - 'We do not yet have details for the councils that cover this location.', - $n - ); - $vars{text_help} .= _("If you submit a problem here the subject and details of the problem will be public, but the problem will <strong>not</strong> be reported to the council."); - $vars{text_help} .= sprintf(_("You can help us by finding a contact email address for local problems for %s and emailing it to us at <a href='mailto:%s'>%s</a>."), $list, $e, $e); - } else { - $vars{text_help} = '<p>' - . _('We do not yet have details for the council that covers this location.') - . ' ' - . _("If you submit a report here it will be left on the site, but not reported to the council – please still leave your report, so that we can show to the council the activity in their area."); - } - $vars{text_help} .= '<input type="hidden" name="council" value="-1">'; - } - - if ($input{skipped}) { - $vars{text_help} .= $q->p(_('Please fill in the form below with details of the problem, -and describe the location as precisely as possible in the details box.')); - } elsif ($q->{site} eq 'scambs') { - $vars{text_help} .= '<p>Please fill in details of the problem below. We won\'t be able -to help unless you leave as much detail as you can, so please describe the exact location of -the problem (e.g. on a wall), what it is, how long it has been there, a description (and a -photo of the problem if you have one), etc.'; - } elsif ($q->{site} eq 'emptyhomes') { - $vars{text_help} .= $q->p(_(<<EOF)); -Please fill in details of the empty property below, saying what type of -property it is e.g. an empty home, block of flats, office etc. Tell us -something about its condition and any other information you feel is relevant. -There is no need for you to give the exact address. Please be polite, concise -and to the point; writing your message entirely in block capitals makes it hard -to read, as does a lack of punctuation. -EOF - } elsif ($details ne 'none') { - $vars{text_help} .= $q->p(_('Please fill in details of the problem below. The council won\'t be able -to help unless you leave as much detail as you can, so please describe the exact location of -the problem (e.g. on a wall), what it is, how long it has been there, a description (and a -photo of the problem if you have one), etc.')); - } else { - $vars{text_help} .= $q->p(_('Please fill in details of the problem below.')); - } - - if (@errors) { - $vars{errors} = '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>'; - } - - $vars{anon} = ($input{anonymous}) ? ' checked' : ($input{title} ? '' : ' checked'); - - $vars{form_heading} = $q->h2(_('Empty property details form')) if $q->{site} eq 'emptyhomes'; - $vars{subject_label} = _('Subject:'); - $vars{detail_label} = _('Details:'); - $vars{photo_label} = _('Photo:'); - $vars{name_label} = _('Name:'); - $vars{email_label} = _('Email:'); - $vars{phone_label} = _('Phone:'); - $vars{optional} = _('(optional)'); - if ($q->{site} eq 'emptyhomes') { - $vars{anonymous} = _('Can we show your name on the site?'); - } else { - $vars{anonymous} = _('Can we show your name publicly?'); - } - $vars{anonymous2} = _('(we never show your email address or phone number)'); - - my $partial_id; - if (my $token = $input{partial}) { - $partial_id = mySociety::AuthToken::retrieve('partial', $token); - if ($partial_id) { - $vars{partial_field} = '<input type="hidden" name="partial" value="' . $token . '">'; - $vars{partial_field} .= '<input type="hidden" name="has_photo" value="' . $q->param('has_photo') . '">'; - } - } - my $photo_input = ''; - if ($allow_photo_upload) { - $photo_input = <<EOF; -<div id="fileupload_normalUI"> -<label for="form_photo">$vars{photo_label}</label> -<input type="file" name="photo" id="form_photo"> -</div> -EOF - } - if ($partial_id && $q->param('has_photo')) { - $vars{photo_field} = "<p>The photo you uploaded was:</p> <p><img src='/photo?id=$partial_id'></p>"; - } else { - $vars{photo_field} = $photo_input; - } - - if ($q->{site} ne 'emptyhomes') { - $vars{text_notes} = - $q->p(_("Please note:")) . - "<ul>" . - $q->li(_("We will only use your personal information in accordance with our <a href=\"/faq#privacy\">privacy policy.</a>")) . - $q->li(_("Please be polite, concise and to the point.")) . - $q->li(_("Please do not be abusive — abusing your council devalues the service for all users.")) . - $q->li(_("Writing your message entirely in block capitals makes it hard to read, as does a lack of punctuation.")) . - $q->li(_("Remember that FixMyStreet is primarily for reporting physical problems that can be fixed. If your problem is not appropriate for submission via this site remember that you can contact your council directly using their own website.")); - $vars{text_notes} .= - $q->li(_("FixMyStreet and the Guardian are providing this service in partnership in <a href=\"/faq#privacy\">certain cities</a>. In those cities, both have access to any information submitted, including names and email addresses, and will use it only to ensure the smooth running of the service, in accordance with their privacy policies.")) - if mySociety::Config::get('COUNTRY') eq 'GB'; - $vars{text_notes} .= "</ul>\n"; - } - - %vars = (%vars, - category => $category, - map_end => FixMyStreet::Map::display_map_end(1), - url_home => Cobrand::url($cobrand, '/', $q), - submit_button => _('Submit') - ); - return (Page::template_include('report-form', $q, Page::template_root($q), %vars), - robots => 'noindex,nofollow', - js => FixMyStreet::Map::header_js(), - ); -} - -# redirect from osgb -sub redirect_from_osgb_to_wgs84 { - my ($q) = @_; - - my $e = $q->param('e'); - my $n = $q->param('n'); - - my ( $lat, $lon ) = Utils::convert_en_to_latlon_truncated( $e, $n ); - - my $lat_lon_url = NewURL( - $q, - -retain => 1, - e => undef, - n => undef, - lat => $lat, - lon => $lon - ); - - print $q->redirect( - -location => $lat_lon_url, - -status => 301, # permanent - ); - - return ''; -} - -sub display_location { - my ($q, @errors) = @_; - my $cobrand = Page::get_cobrand($q); - my @vars = qw(pc x y lat lon all_pins no_pins); - - my %input = (); - my %input_h = (); - - foreach my $key (@vars) { - my $val = $q->param($key); - $input{$key} = defined($val) ? $val : ''; # '0' is valid for longitude - $input_h{$key} = ent( $input{$key} ); - } - - my $latitude = $input{lat}; - my $longitude = $input{lon}; - - # X/Y referring to tiles old-school - (my $x) = $input{x} =~ /^(\d+)/; $x ||= 0; - (my $y) = $input{y} =~ /^(\d+)/; $y ||= 0; - - return front_page( $q, @errors ) - unless ( $x && $y ) - || $input{pc} - || ( $latitude ne '' && $longitude ne '' ); - - if ( $x && $y ) { - - # Convert the tile co-ordinates to real ones. - ( $latitude, $longitude ) = - FixMyStreet::Map::tile_xy_to_wgs84( $x, $y ); - } - elsif ( $latitude && $longitude ) { - - # Don't need to do anything - } - else { - my $error; - try { - ( $latitude, $longitude, $error ) = - FixMyStreet::Geocode::lookup( $input{pc}, $q ); - - debug 'Looked up postcode "%s": lat: "%s", lon: "%s", error: "%s"', - $input{pc}, $latitude, $longitude, $error; - } - catch Error::Simple with { - $error = shift; - }; - return FixMyStreet::Geocode::list_choices( $error, '/', $q ) - if ( ref($error) eq 'ARRAY' ); - return front_page( $q, $error ) if $error; - } - - # Check this location is okay to be displayed for the cobrand - my ($success, $error_msg) = Cobrand::council_check($cobrand, { lat => $latitude, lon => $longitude }, $q, 'display_location'); - return front_page($q, $error_msg) unless $success; - - # Deal with pin hiding/age - my ($hide_link, $hide_text, $all_link, $all_text, $interval); - if ($input{all_pins}) { - $all_link = NewURL($q, -retain=>1, no_pins=>undef, all_pins=>undef); - $all_text = _('Hide stale reports'); - } else { - $all_link = NewURL($q, -retain=>1, no_pins=>undef, all_pins=>1); - $all_text = _('Include stale reports'); - $interval = '6 months'; - } - - my ($on_map_all, $on_map, $around_map, $dist) = FixMyStreet::Map::map_features($q, $latitude, $longitude, $interval); - my @pins; - foreach (@$on_map_all) { - push @pins, [ $_->{latitude}, $_->{longitude}, ($_->{state} eq 'fixed' ? 'green' : 'red'), $_->{id} ]; - } - my $on_list = ''; - foreach (@$on_map) { - my $report_url = NewURL($q, -url => '/report/' . $_->{id}); - $report_url = Cobrand::url($cobrand, $report_url, $q); - $on_list .= '<li><a href="' . $report_url . '">'; - $on_list .= ent($_->{title}) . '</a> <small>('; - $on_list .= Page::prettify_epoch($q, $_->{time}, 1) . ')</small>'; - $on_list .= ' <small>' . _('(fixed)') . '</small>' if $_->{state} eq 'fixed'; - $on_list .= '</li>'; - } - $on_list = $q->li(_('No problems have been reported yet.')) - unless $on_list; - - my $around_list = ''; - foreach (@$around_map) { - my $report_url = Cobrand::url($cobrand, NewURL($q, -url => '/report/' . $_->{id}), $q); - $around_list .= '<li><a href="' . $report_url . '">'; - my $dist = int($_->{distance}*10+0.5); - $dist = $dist / 10; - $around_list .= ent($_->{title}) . '</a> <small>('; - $around_list .= Page::prettify_epoch($q, $_->{time}, 1) . ', '; - $around_list .= $dist . 'km)</small>'; - $around_list .= ' <small>' . _('(fixed)') . '</small>' if $_->{state} eq 'fixed'; - $around_list .= '</li>'; - push @pins, [ $_->{latitude}, $_->{longitude}, ($_->{state} eq 'fixed' ? 'green' : 'red'), $_->{id} ]; - } - $around_list = $q->li(_('No problems found.')) - unless $around_list; - - if ($input{no_pins}) { - $hide_link = NewURL($q, -retain=>1, no_pins=>undef); - $hide_text = _('Show pins'); - @pins = (); - } else { - $hide_link = NewURL($q, -retain=>1, no_pins=>1); - $hide_text = _('Hide pins'); - } - my $map_links = "<p id='sub_map_links'><a id='hide_pins_link' rel='nofollow' href='$hide_link'>$hide_text</a>"; - if (mySociety::Config::get('COUNTRY') eq 'GB') { - $map_links .= " | <a id='all_pins_link' rel='nofollow' href='$all_link'>$all_text</a></p> <input type='hidden' id='all_pins' name='all_pins' value='$input_h{all_pins}'>"; - } else { - $map_links .= "</p>"; - } - - # truncate the lat,lon for nicer rss urls, and strings for outputting - my ( $short_lat, $short_lon ) = - map { Utils::truncate_coordinate($_) } # - ( $latitude, $longitude ); - - my $url_skip = NewURL($q, -retain=>1, - x => undef, 'y' => undef, - latitude => $short_lat, longitude => $short_lon, - 'submit_map'=>1, skipped=>1 - ); - my $pc_h = ent($q->param('pc') || ''); - - my $rss_url; - if ($pc_h) { - $rss_url = "/rss/pc/" . URI::Escape::uri_escape_utf8($pc_h); - } else { - $rss_url = "/rss/l/$short_lat,$short_lon"; - } - $rss_url = Cobrand::url( $cobrand, NewURL($q, -url=> $rss_url), $q); - - my %vars = ( - 'map' => FixMyStreet::Map::display_map($q, - latitude => $short_lat, longitude => $short_lon, - type => 1, - pins => \@pins, - post => $map_links - ), - map_end => FixMyStreet::Map::display_map_end(1), - url_home => Cobrand::url($cobrand, '/', $q), - url_rss => $rss_url, - url_email => Cobrand::url($cobrand, NewURL($q, lat => $short_lat, lon => $short_lon, -url=>'/alert', feed=>"local:$short_lat:$short_lon"), $q), - url_skip => $url_skip, - email_me => _('Email me new local problems'), - rss_alt => _('RSS feed'), - rss_title => _('RSS feed of recent local problems'), - reports_on_around => $on_list, - reports_nearby => $around_list, - heading_problems => _('Problems in this area'), - heading_on_around => _('Reports on and around the map'), - heading_closest => sprintf(_('Closest nearby problems <small>(within %skm)</small>'), $dist), - distance => $dist, - pc_h => $pc_h, - errors => @errors ? '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>' : '', - text_to_report => _('To report a problem, simply - <strong>click on the map</strong> at the correct location.'), - text_skip => sprintf(_("<small>If you cannot see the map, <a href='%s' rel='nofollow'>skip this - step</a>.</small>"), $url_skip), - ); - - my %params = ( - rss => [ _('Recent local problems, FixMyStreet'), $rss_url ], - js => FixMyStreet::Map::header_js(), - robots => 'noindex,nofollow', - ); - - return (Page::template_include('map', $q, Page::template_root($q), %vars), %params); -} - -sub display_problem { - my ($q, $errors, $field_errors) = @_; - my @errors = @$errors; - my %field_errors = %{$field_errors}; - my $cobrand = Page::get_cobrand($q); - push @errors, _('There were problems with your update. Please see below.') if (scalar keys %field_errors); - - my @vars = qw(id name rznvy update fixed add_alert upload_fileid submit_update); - my %input = map { $_ => $q->param($_) || '' } @vars; - my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; - my $base = Cobrand::base_url($cobrand); - - # Some council with bad email software - if ($input{id} =~ /^3D\d+$/) { - $input{id} =~ s/^3D//; - print $q->redirect(-location => $base . '/report/' . $input{id}, -status => 301); - return ''; - } - - # Redirect old /?id=NNN URLs to /report/NNN - if (!@errors && !scalar keys %field_errors && $ENV{SCRIPT_URL} eq '/') { - print $q->redirect(-location => $base . '/report/' . $input{id}, -status => 301); - return ''; - } - - # Get all information from database - return display_location($q, _('Unknown problem ID')) if !$input{id} || $input{id} =~ /\D/; - my $problem = Problems::fetch_problem($input{id}); - return display_location($q, _('Unknown problem ID')) unless $problem; - return front_page($q, _('That report has been removed from FixMyStreet.'), '410 Gone') if $problem->{state} eq 'hidden'; - - my $extra_data = Cobrand::extra_data($cobrand, $q); - my $google_link = Cobrand::base_url_for_emails($cobrand, $extra_data) - . '/report/' . $problem->{id}; - - # truncate the lat,lon for nicer rss urls - my ( $short_lat, $short_lon ) = - map { Utils::truncate_coordinate($_) } # - ( $problem->{latitude}, $problem->{longitude} ); - - my $map_links = ''; - $map_links = "<p id='sub_map_links'>" - . "<a href=\"http://maps.google.co.uk/maps?output=embed&z=16&q=" - . URI::Escape::uri_escape_utf8( $problem->{title} . ' - ' . $google_link ) - . "\@$short_lat,$short_lon\">View on Google Maps</a></p>" - if mySociety::Config::get('COUNTRY') eq 'GB'; - - my $banner; - if ($q->{site} ne 'emptyhomes' && $problem->{state} eq 'confirmed' && $problem->{duration} > 8*7*24*60*60) { - $banner = $q->p({id => 'unknown'}, _('This problem is old and of unknown status.')); - } - if ($problem->{state} eq 'fixed') { - $banner = $q->p({id => 'fixed'}, _('This problem has been fixed') . '.'); - } - - my $contact_url = Cobrand::url($cobrand, NewURL($q, -retain => 1, pc => undef, x => undef, 'y' => undef, -url=>'/contact?id=' . $input{id}), $q); - my $back = Cobrand::url($cobrand, NewURL($q, -url => '/', - lat => $short_lat, lon => $short_lon, - -retain => 1, pc => undef, x => undef, 'y' => undef, id => undef - ), $q); - my $fixed = ($input{fixed}) ? ' checked' : ''; - - my %vars = ( - banner => $banner, - map_start => FixMyStreet::Map::display_map($q, - latitude => $problem->{latitude}, longitude => $problem->{longitude}, - type => 0, - pins => $problem->{used_map} ? [ [ $problem->{latitude}, $problem->{longitude}, 'blue' ] ] : [], - post => $map_links - ), - map_end => FixMyStreet::Map::display_map_end(0), - problem_title => ent($problem->{title}), - problem_meta => Page::display_problem_meta_line($q, $problem), - problem_detail => Page::display_problem_detail($problem), - problem_photo => Page::display_problem_photo($q, $problem), - problem_updates => Page::display_problem_updates($input{id}, $q), - unsuitable => $q->a({rel => 'nofollow', href => $contact_url}, _('Offensive? Unsuitable? Tell us')), - more_problems => '<a href="' . $back . '">' . _('More problems nearby') . '</a>', - url_home => Cobrand::url($cobrand, '/', $q), - alert_link => Cobrand::url($cobrand, NewURL($q, -url => '/alert?type=updates;id='.$input_h{id}, -retain => 1, pc => undef, x => undef, 'y' => undef ), $q), - alert_text => _('Email me updates'), - email_label => _('Email:'), - subscribe => _('Subscribe'), - blurb => _('Receive email when updates are left on this problem'), - cobrand_form_elements1 => Cobrand::form_elements($cobrand, 'alerts', $q), - form_alert_action => Cobrand::url($cobrand, '/alert', $q), - rss_url => Cobrand::url($cobrand, NewURL($q, -retain=>1, -url => '/rss/'.$input_h{id}, pc => undef, x => undef, 'y' => undef, id => undef), $q), - rss_title => _('RSS feed'), - rss_alt => _('RSS feed of updates to this problem'), - update_heading => $q->h2(_('Provide an update')), - field_errors => \%field_errors, - add_alert_checked => ($input{add_alert} || !$input{submit_update}) ? ' checked' : '', - fixedline_box => $problem->{state} eq 'fixed' ? '' : qq{<input type="checkbox" name="fixed" id="form_fixed" value="1"$fixed>}, - fixedline_label => $problem->{state} eq 'fixed' ? '' : qq{<label for="form_fixed">} . _('This problem has been fixed') . qq{</label>}, - name_label => _('Name:'), - update_label => _('Update:'), - alert_label => _('Alert me to future updates'), - post_label => _('Post'), - cobrand_form_elements => Cobrand::form_elements($cobrand, 'updateForm', $q), - form_action => Cobrand::url($cobrand, '/', $q), - input_h => \%input_h, - optional => _('(optional)'), - ); - - $vars{update_blurb} = $q->p($q->small(_('Please note that updates are not sent to the council. If you leave your name it will be public. Your information will only be used in accordance with our <a href="/faq#privacy">privacy policy</a>'))) - unless $q->{site} eq 'emptyhomes'; # No council blurb - - if (@errors) { - $vars{errors} = '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>'; - } - - my $allow_photo_upload = Cobrand::allow_photo_upload($cobrand); - if ($allow_photo_upload) { - my $photo_label = _('Photo:'); - $vars{enctype} = ' enctype="multipart/form-data"'; - $vars{photo_element} = <<EOF; -<div id="fileupload_normalUI"> -<label for="form_photo">$photo_label</label> -<input type="file" name="photo" id="form_photo"> -</div> -EOF - } - - my %params = ( - rss => [ _('Updates to this problem, FixMyStreet'), "/rss/$input_h{id}" ], - robots => 'index, nofollow', - js => FixMyStreet::Map::header_js(), - title => $problem->{title} - ); - - my $page = Page::template_include('problem', $q, Page::template_root($q), %vars); - return ($page, %params); -} - diff --git a/web/iphone/index.cgi b/web/iphone/index.cgi deleted file mode 100755 index cd5199482..000000000 --- a/web/iphone/index.cgi +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/perl -w -I../../perllib -I../../commonlib/perllib - -# iphone/index.cgi: -# Screenshots of the iPhone FixMyStreet application, showing the flow -# -# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: index.cgi,v 1.1 2008-10-29 15:30:15 matthew Exp $ - -use strict; -use Standard -db; -use mySociety::Config; -use mySociety::Web qw(ent); - -# XXX: Ugh, as we're in a subdirectory -BEGIN { - mySociety::Config::set_file("$FindBin::Bin/../../conf/general"); -} - -my @screens = ( -"iphone-1start.png", 'Click the image to progress through the flow of using the iPhone FixMyStreet application. -<br>When launched, the user’s location automatically gets fetched…', -"iphone-2locfound.png", 'They want to take a photo.', -"iphone-pickpicture1.png", 'The simulator doesn’t have a camera, so we’re taken to the photo albums. Let’s pick Hawaii.', -"iphone-pickpicture2.png", 'That red clouds photo looks nice.', -"iphone-pickpicture3.png", 'After any moving or scaling we want, we select the photo.', -"iphone-3picture.png", 'Okay, now we need to edit the summary of the report.', -"iphone-editsummary.png", 'Enter some text.', -"iphone-editsummary2.png", 'And done.', -"iphone-4subject.png", 'I haven’t entered all my details yet, so that’s next.', -"iphone-5details.png", 'Your details are remembered so you only have to enter them once.', -"iphone-6emailkeyboard.png", 'The iPhone has different keyboards, this is the email one.', -"iphone-5details.png", 'Right, we need to enter a name.', -"iphone-editname.png", 'Slightly different keyboard to the email one.', -"iphone-detailsdone.png", 'Okay, details entered.', -"iphone-allready.png", 'That’s everything, hit Report!', -"iphone-7uploading.png", 'Uploading…', -"iphone-8response.png", 'The simulator always thinks it’s in the US, which FixMyStreet won’t like very much.', -"iphone-allready.png", 'Ah well, let’s read the About page instead', -"iphone-9about.png", 'Donate? :)', -); - -sub main { - my $q = shift; - print Page::header($q, title=>'FixMyStreet for iPhone screenshots'); - print '<h1>iPhone simulator simulator</h1>'; - my $screens = scalar @screens / 2; - print <<EOF; -<script type="text/javascript"> -document.write('<style type="text/css">.vv { display: none; }</style>'); -function show(a) { - if (a==$screens) b = 1; - else b = a+1; - document.getElementById('d' + a).style.display='none'; - document.getElementById('d' + b).style.display='block'; -} -</script> -EOF - for (my $i=0; $i<@screens; $i+=2) { - my $t = $i/2 + 1; - my $next = $t + 1; - print "<div id='d$t'"; - print " class='vv'" if $i>1; - print ">"; - print "<p>$screens[$i+1]</p>"; - print "<p align='center'><a onclick='show($t);return false' href='#d$next'><img src='$screens[$i]' width=414 border=0 height=770></a></p>"; - print '</div>'; - } - print Page::footer($q); -} -Page::do_fastcgi(\&main); - diff --git a/web/js.js b/web/js.js deleted file mode 100644 index 07bede2d7..000000000 --- a/web/js.js +++ /dev/null @@ -1,169 +0,0 @@ -/* - * js.js - * FixMyStreet JavaScript - */ - - -YAHOO.util.Event.onContentReady('pc', function() { - if (this.id && this.value == this.defaultValue) { - this.focus(); - } -}); - -YAHOO.util.Event.onContentReady('mapForm', function() { - this.onsubmit = function() { - if (this.submit_problem) { - this.onsubmit = function() { return false; }; - } - - /* XXX Should be in Tilma code only */ - if (this.x) { - this.x.value = fixmystreet.x + 3; - this.y.value = fixmystreet.y + 3; - } - - /* - if (swfu && swfu.getStats().files_queued > 0) { - swfu.startUpload(); - return false; - } - */ - return true; - } -}); - -YAHOO.util.Event.onContentReady('another_qn', function() { - if (!document.getElementById('been_fixed_no').checked && !document.getElementById('been_fixed_unknown').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_unknown', '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'); - }); -}); - -var timer; -function email_alert_close() { - YAHOO.util.Dom.setStyle('email_alert_box', 'display', 'none'); -} -YAHOO.util.Event.onContentReady('email_alert', function() { - YAHOO.util.Event.addListener(this, 'click', function(e) { - if (!document.getElementById('email_alert_box')) - return true; - YAHOO.util.Event.preventDefault(e); - if (YAHOO.util.Dom.getStyle('email_alert_box', 'display') == 'block') { - email_alert_close(); - } else { - var pos = YAHOO.util.Dom.getXY(this); - pos[0] -= 20; pos[1] += 20; - YAHOO.util.Dom.setStyle('email_alert_box', 'display', 'block'); - YAHOO.util.Dom.setXY('email_alert_box', pos); - document.getElementById('alert_rznvy').focus(); - } - }); - YAHOO.util.Event.addListener(this, 'mouseout', function(e) { - timer = window.setTimeout(email_alert_close, 2000); - }); - YAHOO.util.Event.addListener(this, 'mouseover', function(e) { - window.clearTimeout(timer); - }); -}); -YAHOO.util.Event.onContentReady('email_alert_box', function() { - YAHOO.util.Event.addListener(this, 'mouseout', function(e) { - timer = window.setTimeout(email_alert_close, 2000); - }); - YAHOO.util.Event.addListener(this, 'mouseover', function(e) { - window.clearTimeout(timer); - }); -}); - -/* File upload */ -/* -function doSubmit(e) { - e = e || window.event; - if (e.stopPropagation) e.stopPropagation(); - e.cancelBubble = true; - try { - if (swfu.getStats().files_queued > 0) - swfu.startUpload(); - else - return true; - } catch (e) {} - return false; -} - -function uploadDone() { - var m = document.getElementById('mapForm'); - if (m) { - m.submit(); - } else { - document.getElementById('fieldset').submit(); - } -} - -var swfu; -var swfu_settings = { - upload_url : "http://matthew.bci.mysociety.org/upload.cgi", - flash_url : "http://matthew.bci.mysociety.org/jslib/swfupload/swfupload_f9.swf", - file_size_limit : "10240", - file_types : "*.jpg;*.jpeg;*.pjpeg", - file_types_description : "JPEG files", - file_upload_limit : "0", - - swfupload_loaded_handler : function() { - var d = document.getElementById("fieldset"); - if (d) d.onsubmit = doSubmit; - }, - file_queued_handler : function(obj) { - document.getElementById('txtfilename').value = obj.name; - }, - file_queue_error_handler : fileQueueError, -//upload_start_handler : uploadStartEventHandler, - upload_progress_handler : function(obj, bytesLoaded, bytesTotal) { - var percent = Math.ceil((bytesLoaded / bytesTotal) * 100); - obj.id = "singlefile"; - var progress = new FileProgress(obj, this.customSettings.progress_target); - progress.setProgress(percent); - progress.setStatus("Uploading..."); - }, - upload_success_handler : function(obj, server_data) { - obj.id = "singlefile"; - var progress = new FileProgress(obj, this.customSettings.progress_target); - progress.setComplete(); - progress.setStatus("Complete!"); - if (server_data == ' ') { - this.customSettings.upload_successful = false; - } else { - this.customSettings.upload_successful = true; - document.getElementById('upload_fileid').value = server_data; - } - }, - upload_complete_handler : function(obj) { - if (this.customSettings.upload_successful) { - var d = document.getElementById('update_post'); - if (d) d.disabled = 'true'; - uploadDone(); - } else { - obj.id = 'singlefile'; - var progress = new FileProgress(obj, this.customSettings.progress_target); - progress.setError(); - progress.setStatus("File rejected"); - document.getElementById('txtfilename').value = ''; - } - - }, - upload_error_handler : uploadError, - - swfupload_element_id : "fileupload_flashUI", - degraded_element_id : "fileupload_normalUI", - custom_settings : { - upload_successful : false, - progress_target : 'fileupload_flashUI' - } -}; -*/ diff --git a/web/js/fixmystreet.js b/web/js/fixmystreet.js new file mode 100644 index 000000000..4b19dc53e --- /dev/null +++ b/web/js/fixmystreet.js @@ -0,0 +1,60 @@ +/* + * fixmystreet.js + * FixMyStreet JavaScript + */ + +$(function(){ + + $('#pc').focus(); + + $('input[type=submit]').removeAttr('disabled'); + $('#mapForm').submit(function() { + if (this.submit_problem) { + $('input[type=submit]', this).prop("disabled", true); + } + return true; + }); + + if (!$('#been_fixed_no').prop('checked') && !$('#been_fixed_unknown').prop('checked')) { + $('#another_qn').hide(); + } + $('#been_fixed_no').click(function() { + $('#another_qn').show('fast'); + }); + $('#been_fixed_unknown').click(function() { + $('#another_qn').show('fast'); + }); + $('#been_fixed_yes').click(function() { + $('#another_qn').hide('fast'); + }); + + var timer; + function email_alert_close() { + $('#email_alert_box').hide('fast'); + } + + $('#email_alert').click(function(e) { + if (!$('#email_alert_box').length) + return true; + e.preventDefault(); + if ($('#email_alert_box').is(':visible')) { + email_alert_close(); + } else { + var pos = $(this).position(); + $('#email_alert_box').css( { 'left': ( pos.left - 20 ) + 'px', 'top': ( pos.top + 20 ) + 'px' } ); + $('#email_alert_box').show('fast'); + $('#alert_rznvy').focus(); + } + }).hover(function() { + window.clearTimeout(timer); + }, function() { + timer = window.setTimeout(email_alert_close, 2000); + }); + + $('#email_alert_box').hover(function() { + window.clearTimeout(timer); + }, function() { + timer = window.setTimeout(email_alert_close, 2000); + }); + +}); diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js index ed3ca4653..d00079517 100644 --- a/web/js/map-OpenLayers.js +++ b/web/js/map-OpenLayers.js @@ -1,6 +1,4 @@ -YAHOO.util.Event.onContentReady('map', function() { - - fixmystreet.ZOOM_OFFSET = 14; +$(function(){ var perm = new OpenLayers.Control.Permalink(); set_map_config(perm); @@ -11,9 +9,9 @@ YAHOO.util.Event.onContentReady('map', function() { }); fixmystreet.layer_options = OpenLayers.Util.extend({ - zoomOffset: fixmystreet.ZOOM_OFFSET, + zoomOffset: fixmystreet.zoomOffset, transitionEffect: 'resize', - numZoomLevels: 4 + numZoomLevels: fixmystreet.numZoomLevels }, fixmystreet.layer_options); var layer = new fixmystreet.map_type("", fixmystreet.layer_options); fixmystreet.map.addLayer(layer); @@ -24,7 +22,7 @@ YAHOO.util.Event.onContentReady('map', function() { new OpenLayers.Projection("EPSG:4326"), fixmystreet.map.getProjectionObject() ); - fixmystreet.map.setCenter(centre, fixmystreet.zoom || 2); + fixmystreet.map.setCenter(centre, fixmystreet.zoom || 3); } if (document.getElementById('mapForm')) { @@ -43,35 +41,97 @@ YAHOO.util.Event.onContentReady('map', function() { return false; }); - fixmystreet.markers = new OpenLayers.Layer.Markers("Markers"); - var cols = { 'red':'R', 'green':'G', 'blue':'B', 'purple':'P' }; - for (var i=0; i<fixmystreet.pins.length; i++) { - var pin = fixmystreet.pins[i]; - var src = '/i/pin' + cols[pin[2]] + '.gif'; - var size = new OpenLayers.Size(32, 59); - var offset = new OpenLayers.Pixel(-3, -size.h-2); - var icon = new OpenLayers.Icon(src, size, offset); - var loc = new OpenLayers.LonLat(pin[1], pin[0]); - loc.transform( - new OpenLayers.Projection("EPSG:4326"), - fixmystreet.map.getProjectionObject() - ); - var marker = new OpenLayers.Marker(loc, icon); - if (pin[3]) { - marker.id = pin[3]; - marker.events.register('click', marker, function(evt) { - window.location = '/report/' + this.id; - OpenLayers.Event.stop(evt); - }); - } - fixmystreet.markers.addMarker(marker); + // Vector layers must be added onload as IE sucks + if ($.browser.msie) { + $(window).load(fixmystreet_onload); + } else { + fixmystreet_onload(); + } +}); + +function fixmystreet_onload() { + if ( fixmystreet.area ) { + var area = new OpenLayers.Layer.Vector("KML", { + strategies: [ new OpenLayers.Strategy.Fixed() ], + protocol: new OpenLayers.Protocol.HTTP({ + url: "/mapit/area/" + fixmystreet.area + ".kml?simplify_tolerance=0.0001", + format: new OpenLayers.Format.KML() + }) + }); + fixmystreet.map.addLayer(area); + area.events.register('loadend', null, function(a,b,c) { + var bounds = area.getDataExtent(); + if (bounds) { fixmystreet.map.zoomToExtent( bounds ); } + }); + } + + var pin_layer_options = { + styleMap: new OpenLayers.StyleMap({ + 'default': new OpenLayers.Style({ + externalGraphic: "/i/pin${type}.gif", + graphicTitle: "${title}", + graphicWidth: 32, + graphicHeight: 59, + graphicOpacity: 1, + graphicXOffset: -2, + graphicYOffset: -59 + }) + }) + }; + if (fixmystreet.page == 'around') { + pin_layer_options.strategies = [ new OpenLayers.Strategy.BBOX() ]; + pin_layer_options.protocol = new OpenLayers.Protocol.HTTP({ + url: '/ajax', + params: fixmystreet.all_pins ? { all_pins: 1 } : { }, + format: new OpenLayers.Format.FixMyStreet() + }); + } + fixmystreet.markers = new OpenLayers.Layer.Vector("Pins", pin_layer_options); + + var markers = fms_markers_list( fixmystreet.pins, true ); + fixmystreet.markers.addFeatures( markers ); + if (fixmystreet.page == 'around' || fixmystreet.page == 'reports' || fixmystreet.page == 'my') { + fixmystreet.markers.events.register( 'featureselected', fixmystreet.markers, function(evt) { + window.location = '/report/' + evt.feature.attributes.id; + OpenLayers.Event.stop(evt); + }); + var select = new OpenLayers.Control.SelectFeature( fixmystreet.markers ); + fixmystreet.map.addControl( select ); + select.activate(); } fixmystreet.map.addLayer(fixmystreet.markers); -}); + if ( fixmystreet.zoomToBounds ) { + var bounds = fixmystreet.markers.getDataExtent(); + if (bounds) { fixmystreet.map.zoomToExtent( bounds ); } + } +} -YAHOO.util.Event.addListener('hide_pins_link', 'click', function(e) { - YAHOO.util.Event.preventDefault(e); +function fms_markers_list(pins, transform) { + var cols = { 'red':'R', 'green':'G', 'blue':'B', 'purple':'P' }; + var markers = []; + for (var i=0; i<pins.length; i++) { + var pin = pins[i]; + var loc = new OpenLayers.Geometry.Point(pin[1], pin[0]); + if (transform) { + // The Strategy does this for us, so don't do it in that case. + loc.transform( + new OpenLayers.Projection("EPSG:4326"), + fixmystreet.map.getProjectionObject() + ); + } + var marker = new OpenLayers.Feature.Vector(loc, { + type: cols[pin[2]], + id: pin[3], + title: pin[4] + }); + markers.push( marker ); + } + return markers; +} + +$('#hide_pins_link').click(function(e) { + e.preventDefault(); var showhide = [ 'Show pins', 'Hide pins', 'Dangos pinnau', 'Cuddio pinnau', @@ -88,6 +148,35 @@ YAHOO.util.Event.addListener('hide_pins_link', 'click', function(e) { } }); +$('#all_pins_link').click(function(e) { + e.preventDefault(); + fixmystreet.markers.setVisibility(true); + var welsh = 0; + var texts = [ + 'en', 'Include stale reports', 'Hide stale reports', + 'cy', 'Cynnwys hen adroddiadau', 'Cuddio hen adroddiadau' + ]; + for (var i=0; i<texts.length; i+=3) { + if (this.innerHTML == texts[i+1]) { + this.innerHTML = texts[i+2]; + fixmystreet.markers.protocol.options.params = { all_pins: 1 }; + fixmystreet.markers.refresh( { force: true } ); + lang = texts[i]; + } else if (this.innerHTML == texts[i+2]) { + this.innerHTML = texts[i+1]; + fixmystreet.markers.protocol.options.params = { }; + fixmystreet.markers.refresh( { force: true } ); + lang = texts[i]; + } + } + if (lang == 'cy') { + document.getElementById('hide_pins_link').innerHTML = 'Cuddio pinnau'; + } else { + document.getElementById('hide_pins_link').innerHTML = 'Hide pins'; + } +}); + + /* Overridding the buttonDown function of PanZoom so that it does zoomTo(0) rather than zoomToMaxExtent() */ @@ -134,7 +223,8 @@ OpenLayers.Control.PermalinkFMS = OpenLayers.Class(OpenLayers.Control.Permalink, href = href.substring( 0, href.indexOf(separator) ); } - href += separator + OpenLayers.Util.getParameterString(this.createParams(null, this.map.getZoom()+fixmystreet.ZOOM_OFFSET)); + href += separator + OpenLayers.Util.getParameterString(this.createParams(null, this.map.getZoom()+fixmystreet.zoomOffset)); + // Could use mlat/mlon here as well if we are on a page with a marker if (this.anchor && !this.element) { window.location.href = href; } @@ -144,6 +234,24 @@ OpenLayers.Control.PermalinkFMS = OpenLayers.Class(OpenLayers.Control.Permalink, } }); +/* Pan data handler */ +OpenLayers.Format.FixMyStreet = OpenLayers.Class(OpenLayers.Format.JSON, { + read: function(json, filter) { + if (typeof json == 'string') { + obj = OpenLayers.Format.JSON.prototype.read.apply(this, [json, filter]); + } else { + obj = json; + } + if (typeof(obj.current) != 'undefined') + document.getElementById('current').innerHTML = obj.current; + if (typeof(obj.current_near) != 'undefined') + document.getElementById('current_near').innerHTML = obj.current_near; + var markers = fms_markers_list( obj.pins, false ); + return markers; + }, + CLASS_NAME: "OpenLayers.Format.FixMyStreet" +}); + /* Click handler */ OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { defaultHandlerOptions: { @@ -170,12 +278,18 @@ OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { trigger: function(e) { var lonlat = fixmystreet.map.getLonLatFromViewPortPx(e.xy); + if (fixmystreet.page == 'new') { + fixmystreet.markers.features[0].move(lonlat); + } lonlat.transform( fixmystreet.map.getProjectionObject(), new OpenLayers.Projection("EPSG:4326") ); document.getElementById('fixmystreet.latitude').value = lonlat.lat; document.getElementById('fixmystreet.longitude').value = lonlat.lon; + if (fixmystreet.page == 'new') { + return; + } document.getElementById('mapForm').submit(); } }); diff --git a/web/js/map-bing-ol.js b/web/js/map-bing-ol.js index 254d407f4..032ac1e89 100644 --- a/web/js/map-bing-ol.js +++ b/web/js/map-bing-ol.js @@ -1,6 +1,6 @@ function set_map_config(perm) { - fixmystreet.ZOOM_OFFSET = 13; fixmystreet.controls = [ + new OpenLayers.Control.Attribution(), new OpenLayers.Control.ArgParser(), new OpenLayers.Control.Navigation(), perm, @@ -10,6 +10,9 @@ function set_map_config(perm) { } OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, { + attribution: '<a href="http://www.bing.com/maps/">' + + '<img border=0 src="http://dev.virtualearth.net/Branding/logo_powered_by.png"></a>', + initialize: function(name, options) { var url = []; options = OpenLayers.Util.extend({ @@ -18,8 +21,8 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, { numZoomLevels: 18, transitionEffect: "resize", sphericalMercator: true, - buffer: 0, - attribution: "© Microsoft / OS 2010" + buffer: 0 + //attribution: "© Microsoft / OS 2010" }, options); var newArguments = [name, url, options]; OpenLayers.Layer.XYZ.prototype.initialize.apply(this, newArguments); @@ -51,18 +54,19 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, { OpenLayers.Util.indexOf(this.serverResolutions, res) : this.map.getZoom() + this.zoomOffset; - if (z == 16) { + if (z >= 16) { var url = [ - "http://a.os.openstreetmap.org/sv/${z}/${x}/${y}.png", - "http://b.os.openstreetmap.org/sv/${z}/${x}/${y}.png", - "http://c.os.openstreetmap.org/sv/${z}/${x}/${y}.png" + "http://tilma.mysociety.org/sv/${z}/${x}/${y}.png", + "http://a.tilma.mysociety.org/sv/${z}/${x}/${y}.png", + "http://b.tilma.mysociety.org/sv/${z}/${x}/${y}.png", + "http://c.tilma.mysociety.org/sv/${z}/${x}/${y}.png" ]; } else { var url = [ - "http://ecn.t0.tiles.virtualearth.net/tiles/r${id}.png?g=587&productSet=mmOS", - "http://ecn.t1.tiles.virtualearth.net/tiles/r${id}.png?g=587&productSet=mmOS", - "http://ecn.t2.tiles.virtualearth.net/tiles/r${id}.png?g=587&productSet=mmOS", - "http://ecn.t3.tiles.virtualearth.net/tiles/r${id}.png?g=587&productSet=mmOS" + "http://ecn.t0.tiles.virtualearth.net/tiles/r${id}.png?g=701&productSet=mmOS", + "http://ecn.t1.tiles.virtualearth.net/tiles/r${id}.png?g=701&productSet=mmOS", + "http://ecn.t2.tiles.virtualearth.net/tiles/r${id}.png?g=701&productSet=mmOS", + "http://ecn.t3.tiles.virtualearth.net/tiles/r${id}.png?g=701&productSet=mmOS" ]; } var s = '' + x + y + z; diff --git a/web/js/map-bing.js b/web/js/map-bing.js index 748a03525..856e4f188 100644 --- a/web/js/map-bing.js +++ b/web/js/map-bing.js @@ -1,4 +1,4 @@ -YAHOO.util.Event.onContentReady('map', function() { +$(function(){ var centre = new Microsoft.Maps.Location( fixmystreet.latitude, fixmystreet.longitude ); var map = new Microsoft.Maps.Map(document.getElementById("map"), { credentials: fixmystreet.key, diff --git a/web/js/map-google.js b/web/js/map-google.js index ab9bb9042..742b55d47 100644 --- a/web/js/map-google.js +++ b/web/js/map-google.js @@ -1,4 +1,4 @@ -YAHOO.util.Event.onContentReady('map', function() { +$(function(){ var centre = new google.maps.LatLng( fixmystreet.latitude, fixmystreet.longitude ); var map = new google.maps.Map(document.getElementById("map"), { mapTypeId: google.maps.MapTypeId.ROADMAP, diff --git a/web/js/map-tilma-ol.js b/web/js/map-tilma-ol.js deleted file mode 100644 index 5230a5d2c..000000000 --- a/web/js/map-tilma-ol.js +++ /dev/null @@ -1,41 +0,0 @@ -function set_map_config(perm) { - fixmystreet.controls = [ - new OpenLayers.Control.ArgParser(), - perm, - new OpenLayers.Control.Navigation(), - new OpenLayers.Control.PanPanel() - ]; - fixmystreet.map_type = OpenLayers.Layer.Tilma; - fixmystreet.layer_options = { - maxResolution: fixmystreet.maxResolution, - tileSize: new OpenLayers.Size(fixmystreet.tilewidth, fixmystreet.tileheight), - map_type: fixmystreet.tile_type, - numZoomLevels: 1, - zoomOffset: 0 - }; -} - -OpenLayers.Layer.Tilma = OpenLayers.Class(OpenLayers.Layer.XYZ, { - initialize: function(name, options) { - var url = "http://tilma.mysociety.org/tileserver/${type}/${x},${y}/png"; - options = OpenLayers.Util.extend({ - transitionEffect: "resize", - numZoomLevels: 1, - projection: "EPSG:27700", - units: "m", - maxExtent: new OpenLayers.Bounds(0, 0, 700000, 1300000) - }, options); - var newArguments = [name, url, options]; - OpenLayers.Layer.XYZ.prototype.initialize.apply(this, newArguments); - }, - - getURL: function (bounds) { - var res = this.map.getResolution(); - var x = Math.round(bounds.left / (res * this.tileSize.w)); - var y = Math.round(bounds.bottom / (res * this.tileSize.h)); - var path = OpenLayers.String.format(this.url, {'x': x, 'y': y, 'type': this.map_type}); - return path; - }, - - CLASS_NAME: "OpenLayers.Layer.Tilma" -}); diff --git a/web/js/map-tilma.js b/web/js/map-tilma.js deleted file mode 100644 index 1b8cc6450..000000000 --- a/web/js/map-tilma.js +++ /dev/null @@ -1,320 +0,0 @@ -/* - * map-tilma.js - * JavaScript specifically for the tilma based maps - */ - -function compass_pan(e, a) { - YAHOO.util.Event.preventDefault(e); - if (a.home) { - a.x = a.orig_x-drag_x; - a.y = a.orig_y-drag_y; - } - pan(a.x, a.y); -} - -YAHOO.util.Event.onContentReady('compass', function() { - var ua=navigator.userAgent.toLowerCase(); - // if (document.getElementById('mapForm') && (/safari/.test(ua) || /Konqueror/.test(ua))) return; - if (document.getElementById('map').offsetWidth > 510) return; - - var points = this.getElementsByTagName('a'); - YAHOO.util.Event.addListener(points[1], 'click', compass_pan, { x:0, y:fixmystreet.tileheight }); - YAHOO.util.Event.addListener(points[3], 'click', compass_pan, { x:fixmystreet.tilewidth, y:0 }); - YAHOO.util.Event.addListener(points[5], 'click', compass_pan, { x:-fixmystreet.tilewidth, y:0 }); - YAHOO.util.Event.addListener(points[7], 'click', compass_pan, { x:0, y:-fixmystreet.tileheight }); - YAHOO.util.Event.addListener(points[0], 'click', compass_pan, { x:fixmystreet.tilewidth, y:fixmystreet.tileheight }); - YAHOO.util.Event.addListener(points[2], 'click', compass_pan, { x:-fixmystreet.tilewidth, y:fixmystreet.tileheight }); - YAHOO.util.Event.addListener(points[6], 'click', compass_pan, { x:fixmystreet.tilewidth, y:-fixmystreet.tileheight }); - YAHOO.util.Event.addListener(points[8], 'click', compass_pan, { x:-fixmystreet.tilewidth, y:-fixmystreet.tileheight }); - YAHOO.util.Event.addListener(points[4], 'click', compass_pan, { home:1, orig_x:drag_x, orig_y:drag_y }); -}); - -YAHOO.util.Event.onContentReady('map', function() { - var ua=navigator.userAgent.toLowerCase(); - // if (document.getElementById('mapForm') && (/safari/.test(ua) || /Konqueror/.test(ua))) return; - if (document.getElementById('map').offsetWidth > 510) return; - new YAHOO.util.DDMap('map'); - update_tiles(fixmystreet.start_x, fixmystreet.start_y, true); -}); - - -YAHOO.util.Event.addListener('hide_pins_link', 'click', function(e) { - YAHOO.util.Event.preventDefault(e); - if (this.innerHTML == 'Show pins') { - YAHOO.util.Dom.setStyle('pins', 'display', 'block'); - this.innerHTML = 'Hide pins'; - } else if (this.innerHTML == 'Dangos pinnau') { - YAHOO.util.Dom.setStyle('pins', 'display', 'block'); - this.innerHTML = 'Cuddio pinnau'; - } else if (this.innerHTML == 'Cuddio pinnau') { - YAHOO.util.Dom.setStyle('pins', 'display', 'none'); - this.innerHTML = 'Dangos pinnau'; - } else if (this.innerHTML == 'Hide pins') { - YAHOO.util.Dom.setStyle('pins', 'display', 'none'); - this.innerHTML = 'Show pins'; - } -}); -YAHOO.util.Event.addListener('all_pins_link', 'click', function(e) { - YAHOO.util.Event.preventDefault(e); - YAHOO.util.Dom.setStyle('pins', 'display', 'block'); - var welsh = 0; - if (this.innerHTML == 'Include stale reports') { - this.innerHTML = 'Hide stale reports'; - document.getElementById('all_pins').value = '1'; - load_pins(fixmystreet.x, fixmystreet.y); - } else if (this.innerHTML == 'Cynnwys hen adroddiadau') { - this.innerHTML = 'Cuddio hen adroddiadau'; - document.getElementById('all_pins').value = '1'; - welsh = 1; - load_pins(fixmystreet.x, fixmystreet.y); - } else if (this.innerHTML == 'Cuddio hen adroddiadau') { - this.innerHTML = 'Cynnwys hen adroddiadau'; - welsh = 1; - document.getElementById('all_pins').value = ''; - load_pins(fixmystreet.x, fixmystreet.y); - } else if (this.innerHTML == 'Hide stale reports') { - this.innerHTML = 'Include stale reports'; - document.getElementById('all_pins').value = ''; - load_pins(fixmystreet.x, fixmystreet.y); - } - if (welsh) { - document.getElementById('hide_pins_link').innerHTML = 'Cuddio pinnau'; - } else { - document.getElementById('hide_pins_link').innerHTML = 'Hide pins'; - } -}); - -// I love the global -var tile_x = 0; -var tile_y = 0; - -var myAnim; -function pan(x, y) { - if (!myAnim || !myAnim.isAnimated()) { - myAnim = new YAHOO.util.Motion('drag', { points:{by:[x,y]} }, 10, YAHOO.util.Easing.easeOut); - myAnim.useSeconds = false; - //myAnim.onTween.subscribe(function(){ update_tiles(x/10, y/10, false); }); - myAnim.onComplete.subscribe(function(){ - update_tiles(x, y, false); - cleanCache(); - }); - myAnim.animate(); - } -} - -var drag_x = 0; -var drag_y = 0; -function update_tiles(dx, dy, force) { - dx = getInt(dx); dy = getInt(dy); - if (!dx && !dy && !force) return; - var old_drag_x = drag_x; - var old_drag_y = drag_y; - drag_x += dx; - drag_y += dy; - - var drag = document.getElementById('drag'); - drag.style.left = drag_x + 'px'; - drag.style.top = drag_y + 'px'; - - var horizontal = Math.floor(old_drag_x/fixmystreet.tilewidth) - Math.floor(drag_x/fixmystreet.tilewidth); - var vertical = Math.floor(old_drag_y/fixmystreet.tileheight) - Math.floor(drag_y/fixmystreet.tileheight); - if (!horizontal && !vertical && !force) return; - fixmystreet.x += horizontal; - - tile_x += horizontal; - fixmystreet.y -= vertical; - tile_y += vertical; - var url = [ root_path + '/tilma/tileserver/' + fixmystreet.tile_type + '/', fixmystreet.x, '-', (fixmystreet.x+5), ',', fixmystreet.y, '-', (fixmystreet.y+5), '/JSON' ].join(''); - YAHOO.util.Connect.asyncRequest('GET', url, { - success: urls_loaded, failure: urls_not_loaded, - argument: [tile_x, tile_y] - }); - - if (force) return; - load_pins(fixmystreet.x, fixmystreet.y); -} - -function load_pins(x, y) { - if (document.getElementById('formX') && !document.getElementById('problem_submit')) { - all_pins = ''; - if (document.getElementById('all_pins')) { - all_pins = document.getElementById('all_pins').value; - } - var ajax_params = [ 'sx=' + document.getElementById('formX').value, - 'sy=' + document.getElementById('formY').value, - 'x=' + (x+3), - 'y=' + (y+3), - 'all_pins=' + all_pins ]; - - if (document.getElementById('extra_param')) { - ajax_params.push(document.getElementById('extra_param').name + '=' + document.getElementById('extra_param').value); - } - - var url = [ root_path , '/ajax?', ajax_params.join(';')].join(''); - YAHOO.util.Connect.asyncRequest('GET', url, { - success: pins_loaded - }); - } -} - -function pins_loaded(o) { - var data = eval(o.responseText); - document.getElementById('pins').innerHTML = data.pins; - if (typeof(data.current) != 'undefined') - document.getElementById('current').innerHTML = data.current; - if (typeof(data.current_near) != 'undefined') - document.getElementById('current_near').innerHTML = data.current_near; - if (typeof(data.fixed_near) != 'undefined') - document.getElementById('fixed_near').innerHTML = data.fixed_near; -} - -function urls_not_loaded(o) { /* Nothing yet */ } - -// Load 6x6 grid of tiles around current 2x2 -function urls_loaded(o) { - var tiles = eval(o.responseText); - var drag = document.getElementById('drag'); - for (var i=0; i<6; i++) { - var ii = (i + o.argument[1]); - for (var j=0; j<6; j++) { - if (tiles[i][j] == null) continue; - var jj = (j + o.argument[0]); - var id = [ 't', ii, '.', jj ].join(''); - var xx = fixmystreet.x+j; - var yy = fixmystreet.y+5-i; - var img = document.getElementById(id); - if (img) { - if (!img.galleryimg) { img.galleryimg = false; } - img.onclick = drag_check; - tileCache[id] = { x: xx, y: yy, t: img }; - continue; - } - img = cloneNode(); - img.style.top = ((ii-2)*fixmystreet.tileheight) + 'px'; - img.style.left = ((jj-2)*fixmystreet.tilewidth) + 'px'; - img.name = [ 'tile_', xx, '.', yy ].join('') - img.id = id; - if (browser) { - img.style.visibility = 'hidden'; - img.onload=function() { this.style.visibility = 'visible'; } - } - img.src = 'http://tilma.mysociety.org/tileserver/' + fixmystreet.tile_type + '/' + tiles[i][j]; - tileCache[id] = { x: xx, y: yy, t: img }; - drag.appendChild(img); - } - } -} - -var imgElCache; -function cloneNode() { - var img = null; - if (!imgElCache) { - var form = document.getElementById('mapForm'); - if (form) { - img = imgElCache = document.createElement('input'); - img.type = 'image'; - } else { - img = imgElCache = document.createElement('img'); - } - img.onclick = drag_check; - img.style.position = 'absolute'; - img.style.width = fixmystreet.tilewidth + 'px'; - img.style.height = fixmystreet.tileheight + 'px'; - img.galleryimg = false; - img.alt = 'Loading...'; - } else { - img = imgElCache.cloneNode(true); - } - return img; -} - -var tileCache=[]; -function cleanCache() { - for (var i in tileCache) { - if (tileCache[i].x < fixmystreet.x || tileCache[i].x > fixmystreet.x+5 || tileCache[i].y < fixmystreet.y || tileCache[i].y > fixmystreet.y+5) { - var t = tileCache[i].t; - t.parentNode.removeChild(t); // de-leak? - delete tileCache[i]; - } - } -} - -/* Called every mousemove, so on first call, overwrite itself with quicker version */ -function get_posn(ev) { - var posx, posy; - if (ev.pageX || ev.pageY) { - get_posn = function(e) { - return { x: e.pageX, y: e.pageY }; - }; - } else if (ev.clientX || ev.clientY) { - get_posn = function(e) { - return { - x: e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft, - y: e.clientY + document.body.scrollTop + document.documentElement.scrollTop - }; - }; - } else { - get_posn = function(e) { - return { x: undef, y: undef }; - }; - } - return get_posn(ev); -} - -function setCursor(s) { - var drag = document.getElementById('drag'); - var inputs = drag.getElementsByTagName('input'); - for (var i=0; i<inputs.length; i++) { - inputs[i].style.cursor = s; - } -} - -var in_drag = false; -function drag_check(e) { - if (in_drag) { - in_drag = false; - return false; - } - return true; -} - -/* Simpler version of DDProxy */ -var mouse_pos = {}; -YAHOO.util.DDMap = function(id, sGroup, config) { - this.init(id, sGroup, config); -}; -YAHOO.extend(YAHOO.util.DDMap, YAHOO.util.DD, { - scroll: false, - b4MouseDown: function(e) { }, - startDrag: function(x, y) { - mouse_pos = { x: x, y: y }; - setCursor('move'); - in_drag = true; - }, - b4Drag: function(e) { }, - onDrag: function(e) { - var point = get_posn(e); - if (point == mouse_pos) return false; - var dx = point.x-mouse_pos.x; - var dy = point.y-mouse_pos.y; - mouse_pos = point; - update_tiles(dx, dy, false); - }, - endDrag: function(e) { - setCursor('crosshair'); - cleanCache(); - }, - toString: function() { - return ("DDMap " + this.id); - } -}); - -var browser = 1; -var ua=navigator.userAgent.toLowerCase(); -if (!/opera|safari|gecko/.test(ua) && typeof document.all!='undefined') - browser=0; - -function getInt(n) { - n = parseInt(n); return (isNaN(n) ? 0 : n); -} - diff --git a/web/js/southampton.js b/web/js/southampton.js new file mode 100644 index 000000000..1f3e16105 --- /dev/null +++ b/web/js/southampton.js @@ -0,0 +1,50 @@ +/* + * southampton.js + * FixMyStreet JavaScript for Southampton + */ + + +$(function(){ + + $('[placeholder]').focus(function(){ + var input = $(this); + if (input.val() == input.attr('placeholder')) { + input.val(''); + input.removeClass('placeholder'); + input.css({ 'color': '#000000' }); + } + }).blur(function(){ + var input = $(this); + if (input.val() == '' || input.val() == input.attr('placeholder')) { + input.css({ 'color': '#999999' }); + input.val(input.attr('placeholder')); + } + }).blur(); + + $('#form_category').change(function(){ + var category = $(this).val(); + if ('Potholes' == category) { + if (!$('#potholes_extra').length) { + var qns = '<div id="potholes_extra" style="margin:0; display:none;">' + + '<div class="form-field"><label for="form_size">Size:</label>' + + '<select name="detail_size"><option>-- Please select --<option>Unknown' + + '<option>Small: No larger than a dinner plate (up to 30cm/12inches)' + + '<option>Medium: No larger than a dustbin lid (up to 60cm/24inches)' + + '<option>Large: Larger than a dustbin lid (over 60cm/24inches)' + + '</select></div>' + + '<div class="form-field"><label for="form_depth">Depth:</label>' + + '<select name="detail_depth"><option>-- Please select --<option>Unknown' + + '<option>No deeper than a golf ball (up to 4cm/1.5inches)' + + '<option>No deeper than a tennis ball (up to 6.5cm/2.5inches)' + + '<option>Deeper than a tennis ball' + + '</select></div></div>'; + $('#form_title').closest('div.form-field').after(qns); + } + $('#potholes_extra').show('fast'); + } else { + $('#potholes_extra').hide('fast'); + } + }).change(); + +}); + diff --git a/web/json.cgi b/web/json.cgi deleted file mode 100755 index 512750988..000000000 --- a/web/json.cgi +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# json.cgi: -# A small JSON API for FixMyStreet -# -# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved. -# Email: louise@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: json.cgi,v 1.4 2010-01-20 11:31:26 matthew Exp $ - -use strict; -use Error qw(:try); -use JSON; -use Standard; - -sub main { - my $q = shift; - my $problems; - my $type = $q->param('type') || ''; - my $start_date = $q->param('start_date') || ''; - my $end_date = $q->param('end_date') || ''; - if ($start_date !~ /^\d{4}-\d\d-\d\d$/ || $end_date !~ /^\d{4}-\d\d-\d\d$/) { - $problems = { error => 'Invalid dates supplied' }; - } elsif ($type eq 'new_problems') { - $problems = Problems::created_in_interval($start_date, $end_date); - } elsif ($type eq 'fixed_problems') { - $problems = Problems::fixed_in_interval($start_date, $end_date); - } - print $q->header( -type => 'application/json; charset=utf-8' ); - print JSON::to_json($problems); -} - - -Page::do_fastcgi(\&main); - diff --git a/web/photo.cgi b/web/photo.cgi deleted file mode 100755 index bd38e3bf1..000000000 --- a/web/photo.cgi +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# photo.cgi: -# Display a photo for FixMyStreet -# -# Copyright (c) 2006 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: photo.cgi,v 1.11 2008-10-09 14:20:54 matthew Exp $ - -use strict; -use Standard; -use Error qw(:try); -use CGI::Carp; - -sub main { - my $q = shift; - print $q->header(-type => 'image/jpeg', - -expires => '+1y' ); - my $id = $q->param('id'); - my $c = $q->param('c'); - return unless ($id || $c); - my $photo; - if ($c) { - $photo = dbh()->selectrow_arrayref("select photo from comment where - id=? and state = 'confirmed' and photo is not null", {}, $c); - } else { - $photo = dbh()->selectrow_arrayref( "select photo from problem where - id=? and state in ('confirmed', 'fixed', 'partial') and photo is not - null", {}, $id); - } - return unless $photo; - $photo = $photo->[0]; - if ($q->param('tn')) { - $photo = resize($photo, 'x100'); - } elsif ($q->{site} eq 'emptyhomes') { - $photo = resize($photo, '195x'); - } - - print $photo; -} -Page::do_fastcgi(\&main, 0, 1); - -sub resize { - my ($photo, $size) = @_; - use Image::Magick; - my $image = Image::Magick->new; - $image->BlobToImage($photo); - my $err = $image->Scale(geometry => "$size>"); - throw Error::Simple("resize failed: $err") if "$err"; - my @blobs = $image->ImageToBlob(); - undef $image; - return $blobs[0]; -} diff --git a/web/posters/index.cgi b/web/posters/index.cgi deleted file mode 100755 index f26252131..000000000 --- a/web/posters/index.cgi +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/perl -w -I../../perllib -I../../commonlib/perllib - -# posters/index.cgi: -# List of publicity stuff on FixMyStreet -# -# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: index.cgi,v 1.10 2008-10-17 20:19:05 matthew Exp $ - -use strict; -use Standard -db; -use mySociety::Config; -use mySociety::Web qw(ent); - -# XXX: Ugh, as we're in a subdirectory -BEGIN { - mySociety::Config::set_file("$FindBin::Bin/../../conf/general"); -} - -sub main { - my $q = shift; - print Page::header($q, title=>_('Publicity material')); - print body($q); - print Page::footer($q); -} -Page::do_fastcgi(\&main); - -sub body { - my $q = shift; - my $badge = '<a href="http://www.fixmystreet.com/"> <img align="left" hspace="5" src="http://www.fixmystreet.com/i/fms-badge.jpeg" alt="FixMyStreet - report, view or discuss local problems" border="0"></a>'; - return $q->h1(_('Publicity Material')) . - $q->div({style=>'float:left; width:50%'}, - '<p>Copy and paste the text below to add this badge to your site:</p>', $badge, - '<textarea onclick="this.select()" cols=37 rows=5>' . ent($badge) . '</textarea>', - '<p><small>(thanks to Lincolnshire Council for the image)</small></p>' - ) . - $q->div({style=>'float:right; width:47%'}, - $q->p(_('Here are some posters and flyers you can use to publicise FixMyStreet:')) . - '<img hspace="5" src="poster.png" alt="Example poster">' . - $q->h2(_('Posters')) . - $q->ul( - $q->li($q->a({href=>'fixmystreet-poster-a4.pdf'}, _('A4, colour'))), - $q->li($q->a({href=>'fixmystreet-poster-a4-bw.pdf'}, _('A4, black and white'))), - $q->li($q->a({href=>'fixmystreet-poster-a4-bw-low-ink.pdf'}, _('A4, black and white, low ink'))), - $q->li($q->a({href=>'fixmystreet-poster-a4-bw-outlined.pdf'}, _('A4, black and white, outlined'))), - ) . - $q->h2(_('Posters with tags')) . - $q->ul( - $q->li($q->a({href=>'fixmystreet-poster-tags.pdf'}, _('A4, colour'))) . - $q->li($q->a({href=>'fixmystreet-poster-tags-bw.pdf'}, _('A4, black and white'))) . - $q->li($q->a({href=>'fixmystreet-poster-tags-bw-low-ink.pdf'}, _('A4, black and white, low ink'))) . - $q->li($q->a({href=>'fixmystreet-poster-tags-only.pdf'}, _('A4, tags only'))) - ) . - $q->h2(_('Flyers')) . - $q->ul( - $q->li($q->a({href=>'fixmystreet-flyers-colour.pdf'}, _('4 x A6, colour'))), - $q->li($q->a({href=>'fixmystreet-flyers-bw-outlined.pdf'}, _('4 x A6, black and white, outlined'))), - $q->li($q->a({href=>'fixmystreet-flyers-bw-low-ink.pdf'}, _('4 x A6, black and white, low ink'))) - ) - ) - ; -} - diff --git a/web/questionnaire.cgi b/web/questionnaire.cgi deleted file mode 100755 index fdb1c08a4..000000000 --- a/web/questionnaire.cgi +++ /dev/null @@ -1,338 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# 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.53 2009-12-08 17:43:13 louise Exp $ - -use strict; -use Standard; -use Utils; -use Error qw(:try); -use CrossSell; -use mySociety::AuthToken; -use mySociety::Locale; -use mySociety::Web qw(ent); - -sub main { - my $q = shift; - my $out = ''; - if ($q->param('submit')) { - $out = submit_questionnaire($q); - } else { - $out = display_questionnaire($q); - } - print Page::header($q, - title => _('Questionnaire'), - js => FixMyStreet::Map::header_js(), - ); - print $out; - print Page::footer($q); -} -Page::do_fastcgi(\&main); - -sub check_stuff { - my $q = shift; - my $cobrand = Page::get_cobrand($q); - 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}; - my $problem_url = Cobrand::url($cobrand, "/report/$problem_id", $q); - my $contact_url = Cobrand::url($cobrand, "/contact", $q); - throw Error::Simple(sprintf(_("You have already answered this questionnaire. If you have a question, please <a href='%s'>get in touch</a>, or <a href='%s'>view your problem</a>.\n"), $contact_url, $problem_url)) if $questionnaire->{whenanswered}; - - 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; - - my $num_questionnaire = dbh()->selectrow_array( - 'select count(*) from questionnaire where problem_id=?', {}, $problem_id); - my $answered_ever_reported = dbh()->selectrow_array( - 'select id from questionnaire where problem_id in (select id from problem where email=?) and ever_reported is not null', {}, $problem->{email}); - - return ($questionnaire, $problem, $num_questionnaire, $answered_ever_reported); -} - -sub submit_questionnaire { - my $q = shift; - my $cobrand = Page::get_cobrand($q); - my $cobrand_data = Cobrand::extra_data($cobrand, $q); - 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, $num_questionnaire, $problem, $answered_ever_reported); - try { - ($questionnaire, $problem, $num_questionnaire, $answered_ever_reported) = check_stuff($q); - } catch Error::Simple with { - my $e = shift; - $error = $e; - }; - - if ($error) { - my %vars = (heading => _('Questionnaire'), - error => $error->stringify()); - my $template_error = Page::template_include('error', $q, Page::template_root($q), %vars); - return $template_error if $template_error; - return $error; - } - # EHA questionnaires done for you - if ($q->{site} eq 'emptyhomes') { - $input{another} = $num_questionnaire==1 ? 'Yes' : 'No'; - } - - my @errors; - push @errors, _('Please state whether or not the problem has been fixed') unless $input{been_fixed}; - my $ask_ever_reported = Cobrand::ask_ever_reported($cobrand); - if ($ask_ever_reported) { - push @errors, _('Please say whether you\'ve ever reported a problem to your council before') unless $input{reported} || $answered_ever_reported; - } - push @errors, _('Please indicate whether you\'d like to receive another questionnaire') - if ($input{been_fixed} eq 'No' || $input{been_fixed} eq 'Unknown') && !$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 $fh = $q->upload('photo'); - my $image; - if ($fh) { - my $err = Page::check_photo($q, $fh); - push @errors, $err if $err; - try { - $image = Page::process_photo($fh) unless $err; - } catch Error::Simple with { - my $e = shift; - push(@errors, "That image doesn't appear to have uploaded correctly ($e), please try again."); - }; - } - push @errors, _('Please provide some text as well as a photo') - if $image && !$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=?, lastupdate=ms_current_timestamp() - where id=?", {}, $new_state, $problem->{id}) - if $new_state; - - # If it's not fixed and they say it's still not been fixed, record time update - dbh()->do("update problem set lastupdate=ms_current_timestamp() - where id=?", {}, $problem->{id}) - if $input{been_fixed} eq 'No' && $problem->{state} eq 'confirmed'; - - # Record questionnaire response - my $reported = $input{reported} - ? ($input{reported} eq 'Yes' ? 't' : ($input{reported} eq 'No' ? 'f' : undef)) - : undef; - dbh()->do('update questionnaire set whenanswered=ms_current_timestamp(), - ever_reported=?, old_state=?, new_state=? where id=?', {}, - $reported, $problem->{state}, $input{been_fixed} eq 'Unknown' - ? 'unknown' - : ($new_state ? $new_state : $problem->{state}), - $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'); - Utils::workaround_pg_bytea("insert into comment - (problem_id, name, email, website, text, state, mark_fixed, mark_open, photo, lang, cobrand, cobrand_data, confirmed) - values (?, ?, ?, '', ?, 'confirmed', ?, ?, ?, ?, ?, ?, ms_current_timestamp())", 7, - $problem->{id}, $name, $problem->{email}, $update, - $new_state eq 'fixed' ? 't' : 'f', $new_state eq 'confirmed' ? 't' : 'f', - $image, $mySociety::Locale::lang, $cobrand, $cobrand_data - ) - 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{been_fixed} eq 'Unknown') && $input{another} eq 'Yes'; - dbh()->commit(); - - my $out; - my $message; - my $advert_outcome = 1; - if ($input{been_fixed} eq 'Unknown') { - $message = _(<<EOF); -<p>Thank you very much for filling in our questionnaire; if you -get some more information about the status of your problem, please come back to the -site and leave an update.</p> -EOF - } elsif ($new_state eq 'confirmed' || (!$new_state && $problem->{state} eq 'confirmed')) { - my $wtt_url = Cobrand::writetothem_url($cobrand, $cobrand_data); - $wtt_url = "http://www.writetothem.com" if (! $wtt_url); - $message = sprintf(_(<<EOF), $wtt_url); -<p style="font-size:150%%">We're sorry to hear that. We have two suggestions: why not try -<a href="%s">writing direct to your councillor(s)</a> -or, if it's a problem that could be fixed by local people working together, -why not <a href="http://www.pledgebank.com/new">make and publicise a pledge</a>? -</p> -EOF - $advert_outcome = 0; - } else { - $message = _(<<EOF); -<p style="font-size:150%">Thank you very much for filling in our questionnaire; glad to hear it's been fixed.</p> -EOF - } - $out = $message; - my $display_advert = Cobrand::allow_crosssell_adverts($cobrand); - if ($display_advert && $advert_outcome) { - $out .= CrossSell::display_advert($q, $problem->{email}, $problem->{name}, - council => $problem->{council}); - } - my %vars = (message => $message); - my $template_page = Page::template_include('questionnaire-completed', $q, Page::template_root($q), %vars); - return $template_page if ($template_page); - return $out; -} - -sub display_questionnaire { - my ($q, @errors) = @_; - my @vars = qw(token id been_fixed reported update another); - my $cobrand = Page::get_cobrand($q); - my %input = map { $_ => $q->param($_) || '' } @vars; - my %input_h = map { $_ => $q->param($_) ? ent($q->param($_)) : '' } @vars; - - my ($error, $questionnaire, $num_questionnaire, $problem, $answered_ever_reported); - try { - ($questionnaire, $problem, $num_questionnaire, $answered_ever_reported) = check_stuff($q); - } catch Error::Simple with { - my $e = shift; - $error = $e; - }; - if ($error) { - my %vars = (heading => _('Questionnaire'), - error => $error->stringify()); - my $template_error = Page::template_include('error', $q, Page::template_root($q), %vars); - return $template_error if $template_error; - return $error; - } - my $reported_date_time = Page::prettify_epoch($q, $problem->{time}); - my $problem_text = Page::display_problem_text($q, $problem); - my $updates = Page::display_problem_updates($problem->{id}, $q); - - my %vars = ( - input_h => \%input_h, - map_start => FixMyStreet::Map::display_map($q, - latitude => $problem->{latitude}, longitude => $problem->{longitude}, - pins => [ - [ $problem->{latitude}, $problem->{longitude}, $problem->{state} eq 'fixed'?'green':'red' ], - ], - pre => $problem_text, post => $updates - ), - map_end => FixMyStreet::Map::display_map_end(0), - heading => _('Questionnaire'), - yes => _('Yes'), - no => _('No'), - dontknow => _('Don’t know'), - submit => _('Submit questionnaire'), - cobrand_form_elements => Cobrand::form_elements($cobrand, 'questionnaireForm', $q), - form_action => Cobrand::url($cobrand, "/questionnaire", $q), - reported_date_time => $reported_date_time - ); - $vars{been_fixed} = { - yes => $input{been_fixed} eq 'Yes' ? ' checked' : '', - no => $input{been_fixed} eq 'No' ? ' checked' : '', - unknown => $input{been_fixed} eq 'Unknown' ? ' checked' : '', - }; - my $allow_photo_upload = Cobrand::allow_photo_upload($cobrand); - if ($allow_photo_upload) { - $vars{enctype} = 'enctype="multipart/form-data"'; - } - if ($q->{site} eq 'emptyhomes') { - if ($num_questionnaire==1) { - $vars{blurb_eh} = _(<<EOF); -<p>Getting empty homes back into use can be difficult. You shouldn't expect -the property to be back into use yet. But a good council will have started work -and should have reported what they have done on the website. If you are not -satisfied with progress or information from the council, now is the right time -to say. You may also want to try contacting some other people who may be able -to help. For advice on how to do this and other useful information please -go to <a href="http://www.emptyhomes.com/getinvolved/campaign.html">http://www.emptyhomes.com/getinvolved/campaign.html</a>.</p> -EOF - } else { - $vars{blurb_eh} = _(<<EOF); -<p>Getting empty homes back into use can be difficult, but by now a good council -will have made a lot of progress and reported what they have done on the -website. Even so properties can remain empty for many months if the owner is -unwilling or the property is in very poor repair. If nothing has happened or -you are not satisfied with the progress the council is making, now is the right -time to say so. We think it's a good idea to contact some other people who -may be able to help or put pressure on the council For advice on how to do -this and other useful information please go to <a -href="http://www.emptyhomes.com/getinvolved/campaign.html">http://www.emptyhomes.com/getinvolved/campaign.html</a>.</p> -EOF - } - } - - $vars{blurb_report} = _('The details of your problem are available on the right hand side of this page.'); - $vars{blurb_report2} = _('Please take a look at the updates that have been left.') if $updates; - - if (@errors) { - $vars{errors} = '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>'; - } - $vars{fixed_question} = ''; - $vars{fixed_question} .= _('An update marked this problem as fixed.') . ' ' if $problem->{state} eq 'fixed'; - $vars{fixed_question} .= _('Has this problem been fixed?') . '</p>'; - - unless ($answered_ever_reported) { - my %reported = ( - yes => $input{reported} eq 'Yes' ? ' checked' : '', - no => $input{reported} eq 'No' ? ' checked' : '', - ); - my $before = _('Reported before'); - my $first = _('First time'); - $vars{ever_reported} = $q->p(_('Have you ever reported a problem to a council before, or is this your first time?')); - $vars{ever_reported} .= <<EOF; -<p> -<input type="radio" name="reported" id="reported_yes" value="Yes"$reported{yes}> -<label for="reported_yes">$before</label> -<input type="radio" name="reported" id="reported_no" value="No"$reported{no}> -<label for="reported_no">$first</label> -</p> -EOF - } - $vars{blurb_update} = $q->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). For example, what was -your experience of getting the problem fixed?')); - if ($allow_photo_upload) { - my $photo = _('Photo:'); - $vars{photo_input} = <<EOF; -<div id="fileupload_normalUI"> -<label for="form_photo">$photo</label> -<input type="file" name="photo" id="form_photo"> -</div> -EOF - } - my %another = ( - yes => $input{another} eq 'Yes' ? ' checked' : '', - no => $input{another} eq 'No' ? ' checked' : '', - ); - $vars{another_yes} = $another{yes}; - $vars{another_no} = $another{no}; - my $another_qn = _('Would you like to receive another questionnaire in 4 weeks, reminding you to check the status?'); - my $yes = _('Yes'); - my $no = _('No'); - $vars{another_questionnaire} = <<EOF if $q->{site} ne 'emptyhomes'; -<div id="another_qn"> -<p>$another_qn</p> -<p> -<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> -EOF - - return Page::template_include('questionnaire', $q, Page::template_root($q), %vars); -} diff --git a/web/reports.cgi b/web/reports.cgi deleted file mode 100755 index 22dbe344a..000000000 --- a/web/reports.cgi +++ /dev/null @@ -1,341 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# report.cgi: -# Display summary reports for FixMyStreet -# And RSS feeds for those reports etc. -# -# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: reports.cgi,v 1.41 2009-12-08 11:13:30 louise Exp $ - -use strict; -use Standard; -use Encode; -use POSIX qw(strcoll); -use URI::Escape; -use FixMyStreet::Alert; -use mySociety::MaPit; -use mySociety::Web qw(ent NewURL); -use mySociety::VotingArea; - -sub main { - my $q = shift; - my $all = $q->param('all') || 0; - my $rss = $q->param('rss') || ''; - my $cobrand = Page::get_cobrand($q); - - # Look up council name, if given - my $q_council = $q->param('council') || ''; - my $base_url = Cobrand::base_url($cobrand); - - # Manual misspelling redirect - if ($q_council =~ /^rhondda cynon taff$/i) { - print $q->redirect($base_url . '/reports/Rhondda+Cynon+Taf'); - return; - } - - my ($one_council, $area_type, $area_name); - if ($q_council =~ /^(\d\d)([a-z]{2})?([a-z]{2})?$/i) { - my $va_info = mySociety::MaPit::call('area', uc $q_council); - if ($va_info->{error}) { # Given a bad/old ONS code - print $q->redirect($base_url . '/reports'); - return; - } - $area_name = Page::short_name($va_info); - if (length($q_council) == 6) { - $va_info = mySociety::MaPit::call('area', $va_info->{parent_area}); - $area_name = Page::short_name($va_info) . '/' . $area_name; - } - $rss = '/rss' if $rss; - print $q->redirect($base_url . $rss . '/reports/' . $area_name); - return; - } elsif (mySociety::Config::get('COUNTRY') eq 'NO' && $q_council eq 'Oslo') { - $one_council = mySociety::MaPit::call('area', 3); - $area_type = $one_council->{type}; - $area_name = $one_council->{name}; - } elsif (mySociety::Config::get('COUNTRY') eq 'NO' && $q_council =~ /,/) { - my ($kommune, $fylke) = split /\s*,\s*/, $q_council; - my @area_types = Cobrand::area_types($cobrand); - my $areas_k = mySociety::MaPit::call('areas', $kommune, type => \@area_types); - my $areas_f = mySociety::MaPit::call('areas', $fylke, type => \@area_types); - if (keys %$areas_f == 1) { - ($fylke) = values %$areas_f; - foreach (values %$areas_k) { - if ($_->{name} eq $kommune && $_->{parent_area} == $fylke->{id}) { - $one_council = $_; - $area_type = $_->{type}; - $area_name = $_->{name}; - last; - } - } - } - if (!$one_council) { # Given a false council name - print $q->redirect($base_url . '/reports'); - return; - } - } elsif ($q_council =~ /\D/) { - my @area_types = Cobrand::area_types($cobrand); - my $areas = mySociety::MaPit::call('areas', $q_council, type => \@area_types, min_generation=>Cobrand::area_min_generation($cobrand) ); - if (keys %$areas == 1) { - ($one_council) = values %$areas; - $area_type = $one_council->{type}; - $area_name = $one_council->{name}; - } else { - foreach (keys %$areas) { - if ($areas->{$_}->{name} eq $q_council || $areas->{$_}->{name} =~ /^\Q$q_council\E (Borough|City|District|County) Council$/) { - $one_council = $areas->{$_}; - $area_type = $areas->{$_}->{type}; - $area_name = $q_council; - } - } - } - if (!$one_council) { # Given a false council name - print $q->redirect($base_url . '/reports'); - return; - } - } elsif ($q_council =~ /^\d+$/) { - my $va_info = mySociety::MaPit::call('area', $q_council); - if ($va_info->{error}) { - print $q->redirect($base_url . '/reports'); - return; - } - print $q->redirect($base_url . '/reports/' . Page::short_name($va_info)); - return; - } - $all = 0 unless $one_council; - - # Look up ward name, if given - my $q_ward = $q->param('ward') || ''; - my $ward; - if ($one_council && $q_ward) { - my $qw = mySociety::MaPit::call('areas', $q_ward, type => $mySociety::VotingArea::council_child_types, - min_generation => Cobrand::area_min_generation($cobrand)); - foreach my $id (sort keys %$qw) { - if ($qw->{$id}->{parent_area} == $one_council->{id}) { - $ward = $qw->{$id}; - last; - } - } - if (!$ward) { # Given a false ward name - print $q->redirect($base_url . '/reports/' . Page::short_name($one_council)); - return; - } - } - - # RSS - reports for sent reports, area for all problems in area - if ($rss && $one_council) { - my $url = Page::short_name($one_council); - $url .= '/' . Page::short_name($ward) if $ward; - if ($rss eq 'area' && $area_type ne 'DIS' && $area_type ne 'CTY') { - # Two possibilites are the same for one-tier councils, so redirect one to the other - print $q->redirect($base_url . '/rss/reports/' . $url); - return; - } - my $type = 'council_problems'; # Problems sent to a council - my (@params, %title_params); - $title_params{COUNCIL} = $area_name; - push @params, $one_council->{id} if $rss eq 'reports'; - push @params, $ward ? $ward->{id} : $one_council->{id}; - if ($ward && $rss eq 'reports') { - $type = 'ward_problems'; # Problems sent to a council, restricted to a ward - $title_params{WARD} = $q_ward; - } elsif ($rss eq 'area') { - $title_params{NAME} = $ward ? $q_ward : $q_council; - $type = 'area_problems'; # Problems within an area - } - print $q->header( -type => 'application/xml; charset=utf-8' ); - my $xsl = Cobrand::feed_xsl($cobrand); - my $out = FixMyStreet::Alert::generate_rss($type, $xsl, "/$url", \@params, \%title_params, $cobrand, $q); - $out =~ s/matthew.fixmystreet/emptyhomes.matthew.fixmystreet/g if $q->{site} eq 'emptyhomes'; - print $out; - return; - } - - my $areas_info; - if ($one_council) { - $areas_info = mySociety::MaPit::call('areas', [ $one_council->{id}, $one_council->{parent_area} ]) - if $one_council->{parent_area}; - $areas_info = { $one_council->{id} => $one_council } - unless $areas_info; - } else { - # Show all councils on main report page - my @area_types = Cobrand::area_types($cobrand); - $areas_info = mySociety::MaPit::call('areas', \@area_types, min_generation=>Cobrand::area_min_generation($cobrand) ); - } - - my $problems = Problems::council_problems( - $ward ? $ward->{id} : undef, - $one_council ? $one_council->{id} : undef - ); - - my (%fixed, %open); - my $re_councils = join('|', keys %$areas_info); - foreach my $row (@$problems) { - if (!$row->{council}) { - # Problem was not sent to any council, add to possible councils - while ($row->{areas} =~ /,($re_councils)(?=,)/g) { - add_row($row, 0, $1, \%fixed, \%open); - } - } else { - # Add to councils it was sent to - $row->{council} =~ s/\|.*$//; - my @council = split /,/, $row->{council}; - foreach (@council) { - next if $one_council && $_ != $one_council->{id}; - add_row($row, scalar @council, $_, \%fixed, \%open); - } - } - } - - if (!$one_council) { - print Page::header($q, title=>_('Summary reports'), expires=>'+1h'); - print $q->p( - _('This is a summary of all reports on this site; select a particular council to see the reports sent there.'), ' ', - _('Greyed-out lines are councils that no longer exist.') - ); - my $c = 0; - print '<table cellpadding="3" cellspacing="1" border="0">'; - print '<tr><th>' . _('Name') . '</th><th>' . _('New problems') . '</th><th>' . _('Older problems') . '</th>'; - if ($q->{site} ne 'emptyhomes') { - print '<th>' . _('Old problems,<br>state unknown') . '</th>'; - } - print '<th>' . _('Recently fixed') . '</th><th>' . _('Older fixed') . '</th></tr>'; - foreach (sort { strcoll($areas_info->{$a}->{name}, $areas_info->{$b}->{name}) } keys %$areas_info) { - next if mySociety::Config::get('COUNTRY') eq 'NO' && $_ eq 301; # Only want one Oslo - print '<tr align="center"'; - ++$c; - if (mySociety::Config::get('COUNTRY') eq 'GB' && $areas_info->{$_}->{generation_high} == 10) { - print ' class="gone"'; - } elsif ($c%2) { - print ' class="a"'; - } - my $url = Page::short_name($areas_info->{$_}, $areas_info); - my $cobrand_url = Cobrand::url($cobrand, "/reports/$url", $q); - print '><td align="left"><a href="' . $cobrand_url . '">' . - $areas_info->{$_}->{name}; - if ($areas_info->{$_}->{parent_area} && $url =~ /,|%2C/) { - print ', ' . $areas_info->{$areas_info->{$_}->{parent_area}}->{name}; - } - print '</a></td>'; - summary_cell(\@{$open{$_}{new}}); - if ($q->{site} eq 'emptyhomes') { - my $c = 0; - $c += @{$open{$_}{older}} if $open{$_}{older}; - $c += @{$open{$_}{unknown}} if $open{$_}{unknown}; - summary_cell($c); - } else { - summary_cell(\@{$open{$_}{older}}); - summary_cell(\@{$open{$_}{unknown}}); - } - summary_cell(\@{$fixed{$_}{new}}); - summary_cell(\@{$fixed{$_}{old}}); - print "</tr>\n"; - } - print '</table>'; - } else { - my $name = $one_council->{name}; - if (!$name) { - print Page::header($q, title=>_("Summary reports")); - print "Council with identifier " . ent($one_council->{id}). " not found. "; - print $q->a({href => Cobrand::url($cobrand, '/reports', $q) }, 'Show all councils'); - print "."; - } else { - my $rss_url = '/rss/reports/' . Page::short_name($one_council, $areas_info); - my $thing = _('council'); - if ($ward) { - $rss_url .= '/' . Page::short_name($ward); - $thing = 'ward'; - $name = ent($q_ward) . ", $name"; - } - my $all_councils_report = Cobrand::all_councils_report($cobrand); - - my %vars = ( - rss_title => _('RSS feed'), - rss_alt => sprintf(_('RSS feed of problems in this %s'), $thing), - rss_url => Cobrand::url($cobrand, $rss_url, $q), - url_home => Cobrand::url($cobrand, '/', $q), - summary_title => $all_councils_report - ? sprintf(_('This is a summary of all reports for one %s.'), $thing) - : sprintf(_('This is a summary of all reports for this %s.'), $thing), - name => $name, - ); - if ($all && ! $all_councils_report) { - $vars{summary_line} = sprintf(_('You can <a href="%s">see less detail</a>.'), Cobrand::url($cobrand, NewURL($q), $q)); - } elsif (! $all_councils_report) { - $vars{summary_line} = sprintf(_('You can <a href="%s">see more details</a>.'), Cobrand::url($cobrand, NewURL($q, all=>1), $q)); - } elsif ($all) { - $vars{summary_line} = sprintf(_('You can <a href="%s">see less detail</a> or go back and <a href="/reports">show all councils</a>.'), Cobrand::url($cobrand, NewURL($q), $q)); - } else { - $vars{summary_line} = sprintf(_('You can <a href="%s">see more details</a> or go back and <a href="/reports">show all councils</a>.'), Cobrand::url($cobrand, NewURL($q, all=>1), $q)); - } - - my $id = $one_council->{id}; - if ($open{$id}) { - my $col = list_problems($q, _('New problems'), $open{$id}{new}, $all, 0); - my $old = []; - if ($q->{site} eq 'emptyhomes') { - push @$old, @{$open{$id}{older}} if $open{$id}{older}; - push @$old, @{$open{$id}{unknown}} if $open{$id}{unknown}; - } else { - $old = $open{$id}{older}; - } - $col .= list_problems($q, _('Older problems'), $old, $all, 0); - if ($q->{site} ne 'emptyhomes') { - $col .= list_problems($q, _('Old problems, state unknown'), $open{$id}{unknown}, $all, 0); - } - $vars{col_problems} = $col; - } - if ($fixed{$id}) { - my $col = list_problems($q, _('Recently fixed'), $fixed{$id}{new}, $all, 1); - $col .= list_problems($q, _('Old fixed'), $fixed{$id}{old}, $all, 1); - $vars{col_fixed} = $col; - } - print Page::header($q, context => 'reports', title=>sprintf(_('%s - Summary reports'), $name), rss => [ sprintf(_('Problems within %s, FixMyStreet'), $name), Cobrand::url($cobrand, $rss_url, $q) ]); - print Page::template_include('reports', $q, Page::template_root($q), %vars); - } - } - print Page::footer($q); -} -Page::do_fastcgi(\&main); - -sub add_row { - my ($row, $councils, $council, $fixed, $open) = @_; - my $fourweeks = 4*7*24*60*60; - my $duration = ($row->{duration} > 2 * $fourweeks) ? 'old' : 'new'; - my $type = ($row->{duration} > 2 * $fourweeks) - ? 'unknown' - : ($row->{age} > $fourweeks ? 'older' : 'new'); - $row->{councils} = $councils; - #Fixed problems are either old or new - push @{$fixed->{$council}{$duration}}, $row if $row->{state} eq 'fixed'; - # Open problems are either unknown, older, or new - push @{$open->{$council}{$type}}, $row if $row->{state} eq 'confirmed'; -} - -sub summary_cell { - my $c = shift; - $c = 0 unless defined $c; - $c = @$c if ref($c) eq 'ARRAY'; - print '<td>' . $c . '</td>'; -} - -sub list_problems { - my ($q, $title, $problems, $all, $fixed) = @_; - return '' unless $problems; - my $cobrand = Page::get_cobrand($q); - my $out = "<h3>$title</h3>\n<ul>"; - foreach (sort { $fixed ? ($a->{duration} <=> $b->{duration}) : ($a->{age} <=> $b->{age}) } @$problems) { - my $url = Cobrand::url($cobrand, "/report/" . $_->{id}, $q); - $out .= '<li><a href="' . $url . '">'; - $out .= ent($_->{title}); - $out .= '</a>'; - $out .= ' <small>' . _('(sent to both)') . '</small>' if $_->{councils}>1; - $out .= ' <small>' . _('(not sent to council)') . '</small>' if $_->{councils}==0 && $q->{site} ne 'emptyhomes'; - $out .= '<br><small>' . ent($_->{detail}) . '</small>' if $all; - $out .= '</li>'; - } - $out .= '</ul>'; - return $out; -} - diff --git a/web/rss.cgi b/web/rss.cgi deleted file mode 100755 index 1570ca97f..000000000 --- a/web/rss.cgi +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# rss.cgi: -# RSS for FixMyStreet -# -# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: rss.cgi,v 1.38 2009-12-17 15:15:21 louise Exp $ - -use strict; -use Error qw(:try); -use Standard; -use Encode; -use URI::Escape; -use FixMyStreet::Alert; -use FixMyStreet::Geocode; -use mySociety::Locale; -use mySociety::MaPit; -use mySociety::Gaze; -use Utils; - -sub main { - my $q = shift; - my $type = $q->param('type') || ''; - my $cobrand = Page::get_cobrand($q); - my $xsl = Cobrand::feed_xsl($cobrand); - my $out; - if ($type eq 'local_problems') { - $out = rss_local_problems($q); - return unless $out; - } elsif ($type eq 'new_updates') { - my $id = $q->param('id'); - my $problem = Problems::fetch_problem($id); - if (!$problem) { - print $q->header(-status=>'404 Not Found',-type=>'text/html'); - return; - } - my $qs = 'report/' . $id; - $out = FixMyStreet::Alert::generate_rss($type, $xsl, $qs, [$id], undef, $cobrand, $q); - } elsif ($type eq 'new_problems' || $type eq 'new_fixed_problems') { - $out = FixMyStreet::Alert::generate_rss($type, $xsl, '', undef, undef, $cobrand, $q); - } elsif ($type eq 'council_problems') { - my $id = $q->param('id'); - my $qs = '/'.$id; - $out = FixMyStreet::Alert::generate_rss($type, $xsl, $qs, [$id], undef, $cobrand. $q); - } elsif ($type eq 'area_problems') { - my $id = $q->param('id'); - my $va_info = mySociety::MaPit::call('area', $id); - my $qs = '/'.$id; - $out = FixMyStreet::Alert::generate_rss($type, $xsl, $qs, [$id], { NAME => $va_info->{name} }, $cobrand, $q); - } elsif ($type eq 'all_problems') { - $out = FixMyStreet::Alert::generate_rss($type, $xsl, '', undef, undef, $cobrand, $q); - } else { - my $base = mySociety::Config::get('BASE_URL'); - print $q->redirect($base . '/alert'); - return ''; - } - print $q->header( -type => 'application/xml; charset=utf-8' ); - print $out; -} -Page::do_fastcgi(\&main); - -sub rss_local_problems { - my $q = shift; - my $pc = $q->param('pc'); - - my $x = $q->param('x'); - my $y = $q->param('y'); - my $lat = $q->param('lat'); - my $lon = $q->param('lon'); - my $e = $q->param('e'); - my $n = $q->param('n'); - my $d = $q->param('d') || ''; - $d = '' unless $d =~ /^\d+$/; - my $d_str = ''; - $d_str = "/$d" if $d; - my $state = $q->param('state') || 'all'; - $state = 'all' unless $state =~ /^(all|open|fixed)$/; - - # state is getting lost in the redirects. Add it on to the end as a query - my $state_qs = ''; - $state_qs = "?state=$state" unless $state eq 'all'; - - $state = 'confirmed' if $state eq 'open'; - - my $qs; - my %title_params; - my $alert_type; - - my $cobrand = Page::get_cobrand($q); - my $base = Cobrand::base_url($cobrand); - if ($x && $y) { - # 5000/31 as initial scale factor for these RSS feeds, now variable so redirect. - $e = int( ($x * 5000/31) + 0.5 ); - $n = int( ($y * 5000/31) + 0.5 ); - ($lat, $lon) = Utils::convert_en_to_latlon_truncated($e, $n); - print $q->redirect(-location => "$base/rss/l/$lat,$lon$d_str$state_qs"); - return ''; - } elsif ($e && $n) { - ($lat, $lon) = Utils::convert_en_to_latlon_truncated($e, $n); - print $q->redirect(-location => "$base/rss/l/$lat,$lon$d_str$state_qs"); - return ''; - } elsif ($pc) { - my $error; - try { - ($lat, $lon, $error) = FixMyStreet::Geocode::lookup($pc, $q); - } catch Error::Simple with { - $error = shift; - }; - if ($error) { - print $q->redirect(-location => "$base/alert"); - return ''; - } else { - ( $lat, $lon ) = map { Utils::truncate_coordinate($_) } ( $lat, $lon ); - - my $pretty_pc = $pc; - if (mySociety::PostcodeUtil::is_valid_postcode($pc)) { - $pretty_pc = mySociety::PostcodeUtil::canonicalise_postcode($pc); - } - my $pretty_pc_escaped = URI::Escape::uri_escape_utf8($pretty_pc); - $pretty_pc_escaped =~ s/%20/+/g; - $qs = "?pc=$pretty_pc_escaped"; - - $title_params{'POSTCODE'} = $pretty_pc; - } - # pass through rather than redirecting. - } elsif ( $lat || $lon ) { - # pass through - } else { - die "Missing E/N, x/y, lat/lon, or postcode parameter in RSS feed"; - } - - # truncate the lat,lon for nicer urls - ( $lat, $lon ) = map { Utils::truncate_coordinate($_) } ( $lat, $lon ); - - if (!$qs) { - $qs = "?lat=$lat;lon=$lon"; - } - - if ($d) { - $qs .= ";d=$d"; - $d = 100 if $d > 100; - } else { - $d = mySociety::Gaze::get_radius_containing_population($lat, $lon, 200000); - $d = int($d*10+0.5)/10; - mySociety::Locale::in_gb_locale { - $d = sprintf("%f", $d); - } - } - - my $xsl = Cobrand::feed_xsl($cobrand); - - if ($pc) { - $alert_type = 'postcode_local_problems'; - } else { - $alert_type = 'local_problems'; - } - - my @db_params = ($lat, $lon, $d); - - if ($state ne 'all') { - $alert_type .= '_state'; - push @db_params, $state; - } - - return FixMyStreet::Alert::generate_rss($alert_type, $xsl, $qs, \@db_params, \%title_params, $cobrand, $q); -} - diff --git a/web/test.cgi b/web/test.cgi deleted file mode 100755 index c9b36e6b7..000000000 --- a/web/test.cgi +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# test.cgi -# Part of test suite to force an error to check error handling works. -# -# Copyright (c) 2009 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: test.cgi,v 1.1 2009-07-15 20:51:21 matthew Exp $ - -use strict; -use Standard; - -sub main { - my $q = shift; - - print $q->header(-charset => 'utf-8', -content_type => 'text/plain'); - if ($q->param('error')) { - print 10 / 0; # Cause an error by dividing by zero. - } - print "Success"; -} - -Page::do_fastcgi(\&main); - diff --git a/web/tms-signup.cgi b/web/tms-signup.cgi deleted file mode 100755 index 5975a324f..000000000 --- a/web/tms-signup.cgi +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/perl -w -I../perllib - -# tms-signup.cgi -# Showing interest in TextMyStreet -# -# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: tms-signup.cgi,v 1.5 2009-11-11 14:23:05 louise Exp $ - -use strict; -use Standard; -use Digest::SHA1 qw(sha1_hex); -use CrossSell; -use mySociety::AuthToken; -use mySociety::Config; -use mySociety::EmailUtil qw(is_valid_email); -use mySociety::PostcodeUtil qw(is_valid_postcode); -use mySociety::Web qw(ent); - - #dbh()->'insert into textmystreet (name, email, postcode, mobile) values ()'; - -sub main { - my $q = shift; - my $out = ''; - my $title = 'Confirmation'; - if (my $token = $q->param('token')) { - my $data = mySociety::AuthToken::retrieve('tms', $token); - if ($data->{email}) { - $out = tms_token($q, $data); - } else { - $out = $q->p(<<EOF); -Thank you for trying to confirm your interest. We seem to have a problem ourselves -though, so <a href="/contact">please let us know what went on</a> and we'll look into it. -EOF - } - } elsif ($q->param('email')) { - $out = tms_do_subscribe($q); - } else { - $out = tms_updates_form($q); - } - - print Page::header($q, title => $title); - print $out; - print Page::footer($q); -} -Page::do_fastcgi(\&main); - -sub tms_updates_form { - my ($q, @errors) = @_; - my @vars = qw(email name postcode mobile signed_email); - my %input = map { $_ => $q->param($_) || '' } @vars; - my $out = ''; - if (@errors) { - $out .= '<ul class="error"><li>' . join('</li><li>', @errors) . '</li></ul>'; - } - my $cobrand = Page::get_cobrand($q); - my $display_advert = Cobrand::allow_crosssell_adverts($cobrand); - if ($display_advert) { - $out .= CrossSell::display_tms_form(%input); - } - return $out; -} - -sub tms_token { - my ($q, $data) = @_; - my $type = $data->{type}; - my $out = ''; - if ($type eq 'subscribe') { - tms_confirm(%$data); - $out = $q->p('You have successfully registered your interest.'); - $out .= CrossSell::display_advert($q, $data->{email}, $data->{name}, done_tms => 1); - } - return $out; -} - -sub tms_do_subscribe { - my ($q) = @_; - my @vars = qw(email name postcode mobile signed_email); - my %input = map { $_ => $q->param($_) || '' } @vars; - - my @errors; - push @errors, 'Please enter your name' unless $input{name}; - push @errors, 'Please enter a valid email address' unless is_valid_email($input{email}); - push @errors, 'Please enter a valid postcode' unless is_valid_postcode($input{postcode}); - push @errors, 'Please enter a mobile number' unless $input{mobile}; - if (@errors) { - return tms_updates_form($q, @errors); - } - - # See if email address has been signed - if ($input{signed_email}) { - my $out; - if (mySociety::AuthToken::verify_with_shared_secret($input{email}, mySociety::Config::get('AUTH_SHARED_SECRET'), $input{signed_email})) { - tms_confirm(%input); - $out = $q->p('You have successfully registered your interest.'); - return $out; - } - } - - my %h = (); - $h{url} = mySociety::Config::get('BASE_URL') . '/T/' - . mySociety::AuthToken::store('tms', { - type => 'subscribe', - name => $input{name}, - email => $input{email}, - postcode => $input{postcode}, - mobile => $input{mobile}, - }); - dbh()->commit(); - return Page::send_confirmation_email($q, $input{email}, $input{name}, 'tms', %h); -} - -sub tms_confirm { - my %input = @_; - dbh()->do("insert into textmystreet (name, email, postcode, mobile) values (?, ?, ?, ?)", {}, - $input{name}, $input{email}, $input{postcode}, $input{mobile}); - dbh()->commit(); -} - diff --git a/web/upload.cgi b/web/upload.cgi deleted file mode 100755 index aa3f8ce61..000000000 --- a/web/upload.cgi +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/perl -w -I../perllib -I../commonlib/perllib - -# upload.cgi: -# Receiver of flash upload files -# -# Copyright (c) 2008 UK Citizens Online Democracy. All rights reserved. -# Email: matthew@mysociety.org. WWW: http://www.mysociety.org -# -# $Id: upload.cgi,v 1.2 2008-10-09 14:20:54 matthew Exp $ - -use strict; -use Standard -db; - -use Error qw(:try); -use Image::Magick; -use mySociety::Random qw(random_bytes); - -# Main code for index.cgi -sub main { - my $q = shift; - - print $q->header(-type => 'text/plain'); - my $out = ' '; - try { - my $fh = $q->upload('Filedata'); - my $image; - if ($fh) { - $q->delete('photo'); # Can't check content/type when uploaded with Flash - $image = process_photo($fh); - my $name = unpack('H*', random_bytes(12, 1)); - open FP, '>/data/vhost/matthew.bci.mysociety.org/photos/' . $name or throw Error::Simple('could not open file'); - print FP $image; - close FP; - $out = $name; - }; - } catch Error::Simple with { - my $e = shift; - }; - print $out; -} -Page::do_fastcgi(\&main); - -sub process_photo { - my $fh = shift; - my $photo = Image::Magick->new; - my $err = $photo->Read(file => \*$fh); # Mustn't be stringified - close $fh; - throw Error::Simple("read failed: $err") if "$err"; - $err = $photo->Scale(geometry => "250x250>"); - throw Error::Simple("resize failed: $err") if "$err"; - my @blobs = $photo->ImageToBlob(); - undef $photo; - $photo = $blobs[0]; - return $photo; -} - diff --git a/web/xsl.eha.xsl b/web/xsl.eha.xsl index 14015cfd9..41b86ea07 100644 --- a/web/xsl.eha.xsl +++ b/web/xsl.eha.xsl @@ -8,7 +8,7 @@ <head> <title><xsl:value-of select="$title"/> RSS Feed</title> <link rel="stylesheet" href="/css/core.css"/> - <link rel="stylesheet" href="/css/cobrands/emptyhomes/emptyhomes.css"/> + <link rel="stylesheet" href="/cobrands/emptyhomes/css.css"/> </head> <body> <div id="header"><a href="http://www.emptyhomes.com/"><img border="0" src="/i/eha.png" alt="Empty Homes Agency" width="272" height="71"/></a></div> diff --git a/web/xsl.xsl b/web/xsl.xsl index 1aa0eef4b..12a4a93d5 100644 --- a/web/xsl.xsl +++ b/web/xsl.xsl @@ -18,7 +18,7 @@ <h2 class="v">Navigation</h2> <ul id="navigation"> -<li><a href="/">Report a problem</a></li> +<li><a href="/report/new">Report a problem</a></li> <li><a href="/reports">All reports</a></li> <li><a href="/faq">Help</a></li> <li><a href="/contact">Contact</a></li> diff --git a/web/yui/.gitignore b/web/yui/.gitignore deleted file mode 100644 index 796b96d1c..000000000 --- a/web/yui/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/web/yui/utilities.js b/web/yui/utilities.js deleted file mode 100644 index 14a540630..000000000 --- a/web/yui/utilities.js +++ /dev/null @@ -1,305 +0,0 @@ -/* -Copyright (c) 2006, Yahoo! Inc. All rights reserved. -Code licensed under the BSD License: -http://developer.yahoo.net/yui/license.txt -version: 0.12.2.ms1 - bits removed (NFI only, now) -*/ - -if(typeof YAHOO=="undefined"){var YAHOO={};} -YAHOO.namespace=function(){var a=arguments,o=null,i,j,d;for(i=0;i<a.length;++i){d=a[i].split(".");o=YAHOO;for(j=(d[0]=="YAHOO")?1:0;j<d.length;++j){o[d[j]]=o[d[j]]||{};o=o[d[j]];}} -return o;};YAHOO.extend=function(subc,superc,overrides){var F=function(){};F.prototype=superc.prototype;subc.prototype=new F();subc.prototype.constructor=subc;subc.superclass=superc.prototype;if(superc.prototype.constructor==Object.prototype.constructor){superc.prototype.constructor=superc;} -if(overrides){for(var i in overrides){subc.prototype[i]=overrides[i];}}};YAHOO.augment=function(r,s){var rp=r.prototype,sp=s.prototype,a=arguments,i,p;if(a[2]){for(i=2;i<a.length;++i){rp[a[i]]=sp[a[i]];}}else{for(p in sp){if(!rp[p]){rp[p]=sp[p];}}}};YAHOO.namespace("util","widget","example"); -(function(){var Y=YAHOO.util,getStyle,setStyle,id_counter=0,propertyCache={};var ua=navigator.userAgent.toLowerCase(),isOpera=(ua.indexOf('opera')>-1),isSafari=(ua.indexOf('safari')>-1),isGecko=(!isOpera&&!isSafari&&ua.indexOf('gecko')>-1),isIE=(!isOpera&&ua.indexOf('msie')>-1);var patterns={HYPHEN:/(-[a-z])/i};var toCamel=function(property){if(!patterns.HYPHEN.test(property)){return property;} -if(propertyCache[property]){return propertyCache[property];} -while(patterns.HYPHEN.exec(property)){property=property.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());} -propertyCache[property]=property;return property;};if(document.defaultView&&document.defaultView.getComputedStyle){getStyle=function(el,property){var value=null;var computed=document.defaultView.getComputedStyle(el,'');if(computed){value=computed[toCamel(property)];} -return el.style[property]||value;};}else if(document.documentElement.currentStyle&&isIE){getStyle=function(el,property){switch(toCamel(property)){case'opacity':var val=100;try{val=el.filters['DXImageTransform.Microsoft.Alpha'].opacity;}catch(e){try{val=el.filters('alpha').opacity;}catch(e){}} -return val/100;break;default:var value=el.currentStyle?el.currentStyle[property]:null;return(el.style[property]||value);}};}else{getStyle=function(el,property){return el.style[property];};} -if(isIE){setStyle=function(el,property,val){switch(property){case'opacity':if(typeof el.style.filter=='string'){el.style.filter='alpha(opacity='+val*100+')';if(!el.currentStyle||!el.currentStyle.hasLayout){el.style.zoom=1;}} -break;default:el.style[property]=val;}};}else{setStyle=function(el,property,val){el.style[property]=val;};} -YAHOO.util.Dom={get:function(el){if(!el){return null;} -if(typeof el!='string'&&!(el instanceof Array)){return el;} -if(typeof el=='string'){return document.getElementById(el);} -else{var collection=[];for(var i=0,len=el.length;i<len;++i){collection[collection.length]=Y.Dom.get(el[i]);} -return collection;} -return null;},getStyle:function(el,property){property=toCamel(property);var f=function(element){return getStyle(element,property);};return Y.Dom.batch(el,f,Y.Dom,true);},setStyle:function(el,property,val){property=toCamel(property);var f=function(element){setStyle(element,property,val);};Y.Dom.batch(el,f,Y.Dom,true);},getXY:function(el){var f=function(el){if(el.parentNode===null||el.offsetParent===null||this.getStyle(el,'display')=='none'){return false;} -var parentNode=null;var pos=[];var box;if(el.getBoundingClientRect){box=el.getBoundingClientRect();var doc=document;if(!this.inDocument(el)&&parent.document!=document){doc=parent.document;if(!this.isAncestor(doc.documentElement,el)){return false;}} -var scrollTop=Math.max(doc.documentElement.scrollTop,doc.body.scrollTop);var scrollLeft=Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft);return[box.left+scrollLeft,box.top+scrollTop];} -else{pos=[el.offsetLeft,el.offsetTop];parentNode=el.offsetParent;if(parentNode!=el){while(parentNode){pos[0]+=parentNode.offsetLeft;pos[1]+=parentNode.offsetTop;parentNode=parentNode.offsetParent;}} -if(isSafari&&this.getStyle(el,'position')=='absolute'){pos[0]-=document.body.offsetLeft;pos[1]-=document.body.offsetTop;}} -if(el.parentNode){parentNode=el.parentNode;} -else{parentNode=null;} -while(parentNode&&parentNode.tagName.toUpperCase()!='BODY'&&parentNode.tagName.toUpperCase()!='HTML') -{if(Y.Dom.getStyle(parentNode,'display')!='inline'){pos[0]-=parentNode.scrollLeft;pos[1]-=parentNode.scrollTop;} -if(parentNode.parentNode){parentNode=parentNode.parentNode;}else{parentNode=null;}} -return pos;};return Y.Dom.batch(el,f,Y.Dom,true);},getX:function(el){var f=function(el){return Y.Dom.getXY(el)[0];};return Y.Dom.batch(el,f,Y.Dom,true);},getY:function(el){var f=function(el){return Y.Dom.getXY(el)[1];};return Y.Dom.batch(el,f,Y.Dom,true);},setXY:function(el,pos,noRetry){var f=function(el){var style_pos=this.getStyle(el,'position');if(style_pos=='static'){this.setStyle(el,'position','relative');style_pos='relative';} -var pageXY=this.getXY(el);if(pageXY===false){return false;} -var delta=[parseInt(this.getStyle(el,'left'),10),parseInt(this.getStyle(el,'top'),10)];if(isNaN(delta[0])){delta[0]=(style_pos=='relative')?0:el.offsetLeft;} -if(isNaN(delta[1])){delta[1]=(style_pos=='relative')?0:el.offsetTop;} -if(pos[0]!==null){el.style.left=pos[0]-pageXY[0]+delta[0]+'px';} -if(pos[1]!==null){el.style.top=pos[1]-pageXY[1]+delta[1]+'px';} -if(!noRetry){var newXY=this.getXY(el);if((pos[0]!==null&&newXY[0]!=pos[0])||(pos[1]!==null&&newXY[1]!=pos[1])){this.setXY(el,pos,true);}}};Y.Dom.batch(el,f,Y.Dom,true);},setX:function(el,x){Y.Dom.setXY(el,[x,null]);},setY:function(el,y){Y.Dom.setXY(el,[null,y]);},getRegion:function(el){var f=function(el){var region=new Y.Region.getRegion(el);return region;};return Y.Dom.batch(el,f,Y.Dom,true);},getClientWidth:function(){return Y.Dom.getViewportWidth();},getClientHeight:function(){return Y.Dom.getViewportHeight();},getElementsByClassName:function(className,tag,root){var method=function(el){return Y.Dom.hasClass(el,className);};return Y.Dom.getElementsBy(method,tag,root);},hasClass:function(el,className){var re=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)');var f=function(el){return re.test(el['className']);};return Y.Dom.batch(el,f,Y.Dom,true);},addClass:function(el,className){var f=function(el){if(this.hasClass(el,className)){return;} -el['className']=[el['className'],className].join(' ');};Y.Dom.batch(el,f,Y.Dom,true);},removeClass:function(el,className){var re=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)','g');var f=function(el){if(!this.hasClass(el,className)){return;} -var c=el['className'];el['className']=c.replace(re,' ');if(this.hasClass(el,className)){this.removeClass(el,className);}};Y.Dom.batch(el,f,Y.Dom,true);},replaceClass:function(el,oldClassName,newClassName){if(oldClassName===newClassName){return false;} -var re=new RegExp('(?:^|\\s+)'+oldClassName+'(?:\\s+|$)','g');var f=function(el){if(!this.hasClass(el,oldClassName)){this.addClass(el,newClassName);return;} -el['className']=el['className'].replace(re,' '+newClassName+' ');if(this.hasClass(el,oldClassName)){this.replaceClass(el,oldClassName,newClassName);}};Y.Dom.batch(el,f,Y.Dom,true);},generateId:function(el,prefix){prefix=prefix||'yui-gen';el=el||{};var f=function(el){if(el){el=Y.Dom.get(el);}else{el={};} -if(!el.id){el.id=prefix+id_counter++;} -return el.id;};return Y.Dom.batch(el,f,Y.Dom,true);},isAncestor:function(haystack,needle){haystack=Y.Dom.get(haystack);if(!haystack||!needle){return false;} -var f=function(needle){if(haystack.contains&&!isSafari){return haystack.contains(needle);} -else if(haystack.compareDocumentPosition){return!!(haystack.compareDocumentPosition(needle)&16);} -else{var parent=needle.parentNode;while(parent){if(parent==haystack){return true;} -else if(!parent.tagName||parent.tagName.toUpperCase()=='HTML'){return false;} -parent=parent.parentNode;} -return false;}};return Y.Dom.batch(needle,f,Y.Dom,true);},inDocument:function(el){var f=function(el){return this.isAncestor(document.documentElement,el);};return Y.Dom.batch(el,f,Y.Dom,true);},getElementsBy:function(method,tag,root){tag=tag||'*';var nodes=[];if(root){root=Y.Dom.get(root);if(!root){return nodes;}}else{root=document;} -var elements=root.getElementsByTagName(tag);if(!elements.length&&(tag=='*'&&root.all)){elements=root.all;} -for(var i=0,len=elements.length;i<len;++i){if(method(elements[i])){nodes[nodes.length]=elements[i];}} -return nodes;},batch:function(el,method,o,override){var id=el;el=Y.Dom.get(el);var scope=(override)?o:window;if(!el||el.tagName||!el.length){if(!el){return false;} -return method.call(scope,el,o);} -var collection=[];for(var i=0,len=el.length;i<len;++i){if(!el[i]){id=el[i];} -collection[collection.length]=method.call(scope,el[i],o);} -return collection;},getDocumentHeight:function(){var scrollHeight=(document.compatMode!='CSS1Compat')?document.body.scrollHeight:document.documentElement.scrollHeight;var h=Math.max(scrollHeight,Y.Dom.getViewportHeight());return h;},getDocumentWidth:function(){var scrollWidth=(document.compatMode!='CSS1Compat')?document.body.scrollWidth:document.documentElement.scrollWidth;var w=Math.max(scrollWidth,Y.Dom.getViewportWidth());return w;},getViewportHeight:function(){var height=self.innerHeight;var mode=document.compatMode;if((mode||isIE)&&!isOpera){height=(mode=='CSS1Compat')?document.documentElement.clientHeight:document.body.clientHeight;} -return height;},getViewportWidth:function(){var width=self.innerWidth;var mode=document.compatMode;if(mode||isIE){width=(mode=='CSS1Compat')?document.documentElement.clientWidth:document.body.clientWidth;} -return width;}};})();YAHOO.util.Region=function(t,r,b,l){this.top=t;this[1]=t;this.right=r;this.bottom=b;this.left=l;this[0]=l;};YAHOO.util.Region.prototype.contains=function(region){return(region.left>=this.left&®ion.right<=this.right&®ion.top>=this.top&®ion.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(region){var t=Math.max(this.top,region.top);var r=Math.min(this.right,region.right);var b=Math.min(this.bottom,region.bottom);var l=Math.max(this.left,region.left);if(b>=t&&r>=l){return new YAHOO.util.Region(t,r,b,l);}else{return null;}};YAHOO.util.Region.prototype.union=function(region){var t=Math.min(this.top,region.top);var r=Math.max(this.right,region.right);var b=Math.max(this.bottom,region.bottom);var l=Math.min(this.left,region.left);return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Region.getRegion=function(el){var p=YAHOO.util.Dom.getXY(el);var t=p[1];var r=p[0]+el.offsetWidth;var b=p[1]+el.offsetHeight;var l=p[0];return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Point=function(x,y){if(x instanceof Array){y=x[1];x=x[0];} -this.x=this.right=this.left=this[0]=x;this.y=this.top=this.bottom=this[1]=y;};YAHOO.util.Point.prototype=new YAHOO.util.Region(); -YAHOO.util.CustomEvent=function(type,oScope,silent,signature){this.type=type;this.scope=oScope||window;this.silent=silent;this.signature=signature||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){} -var onsubscribeType="_YUICEOnSubscribe";if(type!==onsubscribeType){this.subscribeEvent=new YAHOO.util.CustomEvent(onsubscribeType,this,true);}};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(fn,obj,override){if(this.subscribeEvent){this.subscribeEvent.fire(fn,obj,override);} -this.subscribers.push(new YAHOO.util.Subscriber(fn,obj,override));},unsubscribe:function(fn,obj){var found=false;for(var i=0,len=this.subscribers.length;i<len;++i){var s=this.subscribers[i];if(s&&s.contains(fn,obj)){this._delete(i);found=true;}} -return found;},fire:function(){var len=this.subscribers.length;if(!len&&this.silent){return true;} -var args=[],ret=true,i;for(i=0;i<arguments.length;++i){args.push(arguments[i]);} -var argslength=args.length;if(!this.silent){} -for(i=0;i<len;++i){var s=this.subscribers[i];if(s){if(!this.silent){} -var scope=s.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var param=null;if(args.length>0){param=args[0];} -ret=s.fn.call(scope,param,s.obj);}else{ret=s.fn.call(scope,this.type,args,s.obj);} -if(false===ret){if(!this.silent){} -return false;}}} -return true;},unsubscribeAll:function(){for(var i=0,len=this.subscribers.length;i<len;++i){this._delete(len-1-i);}},_delete:function(index){var s=this.subscribers[index];if(s){delete s.fn;delete s.obj;} -this.subscribers.splice(index,1);}};YAHOO.util.Subscriber=function(fn,obj,override){this.fn=fn;this.obj=obj||null;this.override=override;};YAHOO.util.Subscriber.prototype.getScope=function(defaultScope){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}} -return defaultScope;};YAHOO.util.Subscriber.prototype.contains=function(fn,obj){if(obj){return(this.fn==fn&&this.obj==obj);}else{return(this.fn==fn);}};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var loadComplete=false;var listeners=[];var unloadListeners=[];var legacyEvents=[];var legacyHandlers=[];var retryCount=0;var onAvailStack=[];var legacyMap=[];var counter=0;return{POLL_RETRYS:200,POLL_INTERVAL:20,EL:0,TYPE:1,FN:2,WFN:3,OBJ:3,ADJ_SCOPE:4,isSafari:(/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),isIE:(!this.isSafari&&!navigator.userAgent.match(/opera/gi)&&navigator.userAgent.match(/msie/gi)),_interval:null,startInterval:function(){if(!this._interval){var self=this;var callback=function(){self._tryPreloadAttach();};this._interval=setInterval(callback,this.POLL_INTERVAL);}},onAvailable:function(p_id,p_fn,p_obj,p_override){onAvailStack.push({id:p_id,fn:p_fn,obj:p_obj,override:p_override,checkReady:false});retryCount=this.POLL_RETRYS;this.startInterval();},onContentReady:function(p_id,p_fn,p_obj,p_override){onAvailStack.push({id:p_id,fn:p_fn,obj:p_obj,override:p_override,checkReady:true});retryCount=this.POLL_RETRYS;this.startInterval();},addListener:function(el,sType,fn,obj,override){if(!fn||!fn.call){return false;} -if(this._isValidCollection(el)){var ok=true;for(var i=0,len=el.length;i<len;++i){ok=this.on(el[i],sType,fn,obj,override)&&ok;} -return ok;}else if(typeof el=="string"){var oEl=this.getEl(el);if(oEl){el=oEl;}else{this.onAvailable(el,function(){YAHOO.util.Event.on(el,sType,fn,obj,override);});return true;}} -if(!el){return false;} -if("unload"==sType&&obj!==this){unloadListeners[unloadListeners.length]=[el,sType,fn,obj,override];return true;} -var scope=el;if(override){if(override===true){scope=obj;}else{scope=override;}} -var wrappedFn=function(e){return fn.call(scope,YAHOO.util.Event.getEvent(e),obj);};var li=[el,sType,fn,wrappedFn,scope];var index=listeners.length;listeners[index]=li;if(this.useLegacyEvent(el,sType)){var legacyIndex=this.getLegacyIndex(el,sType);if(legacyIndex==-1||el!=legacyEvents[legacyIndex][0]){legacyIndex=legacyEvents.length;legacyMap[el.id+sType]=legacyIndex;legacyEvents[legacyIndex]=[el,sType,el["on"+sType]];legacyHandlers[legacyIndex]=[];el["on"+sType]=function(e){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(e),legacyIndex);};} -legacyHandlers[legacyIndex].push(li);}else{try{this._simpleAdd(el,sType,wrappedFn,false);}catch(e){this.removeListener(el,sType,fn);return false;}} -return true;},fireLegacyEvent:function(e,legacyIndex){var ok=true;var le=legacyHandlers[legacyIndex];for(var i=0,len=le.length;i<len;++i){var li=le[i];if(li&&li[this.WFN]){var scope=li[this.ADJ_SCOPE];var ret=li[this.WFN].call(scope,e);ok=(ok&&ret);}} -return ok;},getLegacyIndex:function(el,sType){var key=this.generateId(el)+sType;if(typeof legacyMap[key]=="undefined"){return-1;}else{return legacyMap[key];}},useLegacyEvent:function(el,sType){if(!el.addEventListener&&!el.attachEvent){return true;}else if(this.isSafari){if("click"==sType||"dblclick"==sType){return true;}} -return false;},removeListener:function(el,sType,fn){var i,len;if(typeof el=="string"){el=this.getEl(el);}else if(this._isValidCollection(el)){var ok=true;for(i=0,len=el.length;i<len;++i){ok=(this.removeListener(el[i],sType,fn)&&ok);} -return ok;} -if(!fn||!fn.call){return this.purgeElement(el,false,sType);} -if("unload"==sType){for(i=0,len=unloadListeners.length;i<len;i++){var li=unloadListeners[i];if(li&&li[0]==el&&li[1]==sType&&li[2]==fn){unloadListeners.splice(i,1);return true;}} -return false;} -var cacheItem=null;var index=arguments[3];if("undefined"==typeof index){index=this._getCacheIndex(el,sType,fn);} -if(index>=0){cacheItem=listeners[index];} -if(!el||!cacheItem){return false;} -if(this.useLegacyEvent(el,sType)){var legacyIndex=this.getLegacyIndex(el,sType);var llist=legacyHandlers[legacyIndex];if(llist){for(i=0,len=llist.length;i<len;++i){li=llist[i];if(li&&li[this.EL]==el&&li[this.TYPE]==sType&&li[this.FN]==fn){llist.splice(i,1);break;}}}}else{try{this._simpleRemove(el,sType,cacheItem[this.WFN],false);}catch(e){return false;}} -delete listeners[index][this.WFN];delete listeners[index][this.FN];listeners.splice(index,1);return true;},getTarget:function(ev,resolveTextNode){var t=ev.target||ev.srcElement;return this.resolveTextNode(t);},resolveTextNode:function(node){if(node&&3==node.nodeType){return node.parentNode;}else{return node;}},getPageX:function(ev){var x=ev.pageX;if(!x&&0!==x){x=ev.clientX||0;if(this.isIE){x+=this._getScrollLeft();}} -return x;},getPageY:function(ev){var y=ev.pageY;if(!y&&0!==y){y=ev.clientY||0;if(this.isIE){y+=this._getScrollTop();}} -return y;},getXY:function(ev){return[this.getPageX(ev),this.getPageY(ev)];},getRelatedTarget:function(ev){var t=ev.relatedTarget;if(!t){if(ev.type=="mouseout"){t=ev.toElement;}else if(ev.type=="mouseover"){t=ev.fromElement;}} -return this.resolveTextNode(t);},getTime:function(ev){if(!ev.time){var t=new Date().getTime();try{ev.time=t;}catch(e){return t;}} -return ev.time;},stopEvent:function(ev){this.stopPropagation(ev);this.preventDefault(ev);},stopPropagation:function(ev){if(ev.stopPropagation){ev.stopPropagation();}else{ev.cancelBubble=true;}},preventDefault:function(ev){if(ev.preventDefault){ev.preventDefault();}else{ev.returnValue=false;}},getEvent:function(e){var ev=e||window.event;if(!ev){var c=this.getEvent.caller;while(c){ev=c.arguments[0];if(ev&&Event==ev.constructor){break;} -c=c.caller;}} -return ev;},getCharCode:function(ev){return ev.charCode||ev.keyCode||0;},_getCacheIndex:function(el,sType,fn){for(var i=0,len=listeners.length;i<len;++i){var li=listeners[i];if(li&&li[this.FN]==fn&&li[this.EL]==el&&li[this.TYPE]==sType){return i;}} -return-1;},generateId:function(el){var id=el.id;if(!id){id="yuievtautoid-"+counter;++counter;el.id=id;} -return id;},_isValidCollection:function(o){return(o&&o.length&&typeof o!="string"&&!o.tagName&&!o.alert&&typeof o[0]!="undefined");},elCache:{},getEl:function(id){return document.getElementById(id);},clearCache:function(){},_load:function(e){loadComplete=true;var EU=YAHOO.util.Event;if(this.isIE){EU._simpleRemove(window,"load",EU._load);}},_tryPreloadAttach:function(){if(this.locked){return false;} -this.locked=true;var tryAgain=!loadComplete;if(!tryAgain){tryAgain=(retryCount>0);} -var notAvail=[];for(var i=0,len=onAvailStack.length;i<len;++i){var item=onAvailStack[i];if(item){var el=this.getEl(item.id);if(el){if(!item.checkReady||loadComplete||el.nextSibling||(document&&document.body)){var scope=el;if(item.override){if(item.override===true){scope=item.obj;}else{scope=item.override;}} -item.fn.call(scope,item.obj);onAvailStack[i]=null;}}else{notAvail.push(item);}}} -retryCount=(notAvail.length===0)?0:retryCount-1;if(tryAgain){this.startInterval();}else{clearInterval(this._interval);this._interval=null;} -this.locked=false;return true;},purgeElement:function(el,recurse,sType){var elListeners=this.getListeners(el,sType);if(elListeners){for(var i=0,len=elListeners.length;i<len;++i){var l=elListeners[i];this.removeListener(el,l.type,l.fn);}} -if(recurse&&el&&el.childNodes){for(i=0,len=el.childNodes.length;i<len;++i){this.purgeElement(el.childNodes[i],recurse,sType);}}},getListeners:function(el,sType){var elListeners=[];if(listeners&&listeners.length>0){for(var i=0,len=listeners.length;i<len;++i){var l=listeners[i];if(l&&l[this.EL]===el&&(!sType||sType===l[this.TYPE])){elListeners.push({type:l[this.TYPE],fn:l[this.FN],obj:l[this.OBJ],adjust:l[this.ADJ_SCOPE],index:i});}}} -return(elListeners.length)?elListeners:null;},_unload:function(e){var EU=YAHOO.util.Event,i,j,l,len,index;for(i=0,len=unloadListeners.length;i<len;++i){l=unloadListeners[i];if(l){var scope=window;if(l[EU.ADJ_SCOPE]){if(l[EU.ADJ_SCOPE]===true){scope=l[EU.OBJ];}else{scope=l[EU.ADJ_SCOPE];}} -l[EU.FN].call(scope,EU.getEvent(e),l[EU.OBJ]);unloadListeners[i]=null;l=null;scope=null;}} -unloadListeners=null;if(listeners&&listeners.length>0){j=listeners.length;while(j){index=j-1;l=listeners[index];if(l){EU.removeListener(l[EU.EL],l[EU.TYPE],l[EU.FN],index);} -j=j-1;} -l=null;EU.clearCache();} -for(i=0,len=legacyEvents.length;i<len;++i){legacyEvents[i][0]=null;legacyEvents[i]=null;} -legacyEvents=null;EU._simpleRemove(window,"unload",EU._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var dd=document.documentElement,db=document.body;if(dd&&(dd.scrollTop||dd.scrollLeft)){return[dd.scrollTop,dd.scrollLeft];}else if(db){return[db.scrollTop,db.scrollLeft];}else{return[0,0];}},_simpleAdd:function(){if(window.addEventListener){return function(el,sType,fn,capture){el.addEventListener(sType,fn,(capture));};}else if(window.attachEvent){return function(el,sType,fn,capture){el.attachEvent("on"+sType,fn);};}else{return function(){};}}(),_simpleRemove:function(){if(window.removeEventListener){return function(el,sType,fn,capture){el.removeEventListener(sType,fn,(capture));};}else if(window.detachEvent){return function(el,sType,fn){el.detachEvent("on"+sType,fn);};}else{return function(){};}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;if(document&&document.body){EU._load();}else{EU._simpleAdd(window,"load",EU._load);} -EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();} -YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(p_type,p_fn,p_obj,p_override){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[p_type];if(ce){ce.subscribe(p_fn,p_obj,p_override);}else{this.__yui_subscribers=this.__yui_subscribers||{};var subs=this.__yui_subscribers;if(!subs[p_type]){subs[p_type]=[];} -subs[p_type].push({fn:p_fn,obj:p_obj,override:p_override});}},unsubscribe:function(p_type,p_fn,p_obj){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[p_type];if(ce){return ce.unsubscribe(p_fn,p_obj);}else{return false;}},createEvent:function(p_type,p_config){this.__yui_events=this.__yui_events||{};var opts=p_config||{};var events=this.__yui_events;if(events[p_type]){}else{var scope=opts.scope||this;var silent=opts.silent||null;var ce=new YAHOO.util.CustomEvent(p_type,scope,silent,YAHOO.util.CustomEvent.FLAT);events[p_type]=ce;if(opts.onSubscribeCallback){ce.subscribeEvent.subscribe(opts.onSubscribeCallback);} -this.__yui_subscribers=this.__yui_subscribers||{};var qs=this.__yui_subscribers[p_type];if(qs){for(var i=0;i<qs.length;++i){ce.subscribe(qs[i].fn,qs[i].obj,qs[i].override);}}} -return events[p_type];},fireEvent:function(p_type,arg1,arg2,etc){this.__yui_events=this.__yui_events||{};var ce=this.__yui_events[p_type];if(ce){var args=[];for(var i=1;i<arguments.length;++i){args.push(arguments[i]);} -return ce.fire.apply(ce,args);}else{return null;}},hasEvent:function(type){if(this.__yui_events){if(this.__yui_events[type]){return true;}} -return false;}};YAHOO.util.Connect={_msxml_progid:['MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'],_poll:{},_timeOut:{},_transaction_id:0,createXhrObject:function(transactionId) -{var obj,http;try -{http=new XMLHttpRequest();obj={conn:http,tId:transactionId};} -catch(e) -{for(var i=0;i<this._msxml_progid.length;++i){try -{http=new ActiveXObject(this._msxml_progid[i]);obj={conn:http,tId:transactionId};break;} -catch(e){}}} -finally -{return obj;}},getConnectionObject:function() -{var o;var tId=this._transaction_id;try -{o=this.createXhrObject(tId);if(o){this._transaction_id++;}} -catch(e){} -finally -{return o;}},asyncRequest:function(method,uri,callback) -{var o=this.getConnectionObject();if(!o){return null;} -else{ -o.conn.open(method,uri,true); -this.handleReadyState(o,callback);o.conn.send(null);return o;}},handleReadyState:function(o,callback) -{var oConn=this;if(callback&&callback.timeout){this._timeOut[o.tId]=window.setTimeout(function(){oConn.abort(o,callback,true);},callback.timeout);} -this._poll[o.tId]=window.setInterval(function(){if(o.conn&&o.conn.readyState==4){window.clearInterval(oConn._poll[o.tId]);delete oConn._poll[o.tId];if(callback&&callback.timeout){delete oConn._timeOut[o.tId];} -oConn.handleTransactionResponse(o,callback);}},50);},handleTransactionResponse:function(o,callback,isAbort) -{if(!callback){this.releaseObject(o);return;} -var httpStatus,responseObject;try -{if(o.conn.status!==undefined&&o.conn.status!=0){httpStatus=o.conn.status;} -else{httpStatus=13030;}} -catch(e){httpStatus=13030;} -if(httpStatus>=200&&httpStatus<300){try -{responseObject=this.createResponseObject(o,callback.argument);if(callback.success){if(!callback.scope){callback.success(responseObject);} -else{callback.success.apply(callback.scope,[responseObject]);}}} -catch(e){}} -else{try -{switch(httpStatus){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:responseObject=this.createExceptionObject(o.tId,callback.argument,(isAbort?isAbort:false));if(callback.failure){if(!callback.scope){callback.failure(responseObject);} -else{callback.failure.apply(callback.scope,[responseObject]);}} -break;default:responseObject=this.createResponseObject(o,callback.argument);if(callback.failure){if(!callback.scope){callback.failure(responseObject);} -else{callback.failure.apply(callback.scope,[responseObject]);}}}} -catch(e){}} -this.releaseObject(o);responseObject=null;},createResponseObject:function(o,callbackArg) -{var obj={};var headerObj={};try -{var headerStr=o.conn.getAllResponseHeaders();var header=headerStr.split('\n');for(var i=0;i<header.length;i++){var delimitPos=header[i].indexOf(':');if(delimitPos!=-1){headerObj[header[i].substring(0,delimitPos)]=header[i].substring(delimitPos+2);}}} -catch(e){} -obj.tId=o.tId;obj.status=o.conn.status;obj.statusText=o.conn.statusText;obj.getResponseHeader=headerObj;obj.getAllResponseHeaders=headerStr;obj.responseText=o.conn.responseText;obj.responseXML=o.conn.responseXML;if(typeof callbackArg!==undefined){obj.argument=callbackArg;} -return obj;},createExceptionObject:function(tId,callbackArg,isAbort) -{var COMM_CODE=0;var COMM_ERROR='communication failure';var ABORT_CODE=-1;var ABORT_ERROR='transaction aborted';var obj={};obj.tId=tId;if(isAbort){obj.status=ABORT_CODE;obj.statusText=ABORT_ERROR;} -else{obj.status=COMM_CODE;obj.statusText=COMM_ERROR;} -if(callbackArg){obj.argument=callbackArg;} -return obj;} -,abort:function(o,callback,isTimeout) -{if(this.isCallInProgress(o)){o.conn.abort();window.clearInterval(this._poll[o.tId]);delete this._poll[o.tId];if(isTimeout){delete this._timeOut[o.tId];} -this.handleTransactionResponse(o,callback,true);return true;} -else{return false;}},isCallInProgress:function(o) -{if(o.conn){return o.conn.readyState!=4&&o.conn.readyState!=0;} -else{return false;}},releaseObject:function(o) -{o.conn=null;o=null;}}; -YAHOO.util.Anim=function(el,attributes,duration,method){if(el){this.init(el,attributes,duration,method);}};YAHOO.util.Anim.prototype={patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(attr,start,end){return this.method(this.currentFrame,start,end-start,this.totalFrames);},setAttribute:function(attr,val,unit){if(this.patterns.noNegatives.test(attr)){val=(val>0)?val:0;} -YAHOO.util.Dom.setStyle(this.getEl(),attr,val+unit);},getAttribute:function(attr){var el=this.getEl();var val=YAHOO.util.Dom.getStyle(el,attr);if(val!=='auto'&&!this.patterns.offsetUnit.test(val)){return parseFloat(val);} -var a=this.patterns.offsetAttribute.exec(attr)||[];var pos=!!(a[3]);var box=!!(a[2]);if(box||(YAHOO.util.Dom.getStyle(el,'position')=='absolute'&&pos)){val=el['offset'+a[0].charAt(0).toUpperCase()+a[0].substr(1)];}else{val=0;} -return val;},getDefaultUnit:function(attr){if(this.patterns.defaultUnit.test(attr)){return'px';} -return'';},setRuntimeAttribute:function(attr){var start;var end;var attributes=this.attributes;this.runtimeAttributes[attr]={};var isset=function(prop){return(typeof prop!=='undefined');};if(!isset(attributes[attr]['to'])&&!isset(attributes[attr]['by'])){return false;} -start=(isset(attributes[attr]['from']))?attributes[attr]['from']:this.getAttribute(attr);if(isset(attributes[attr]['to'])){end=attributes[attr]['to'];}else if(isset(attributes[attr]['by'])){if(start.constructor==Array){end=[];for(var i=0,len=start.length;i<len;++i){end[i]=start[i]+attributes[attr]['by'][i];}}else{end=start+attributes[attr]['by'];}} -this.runtimeAttributes[attr].start=start;this.runtimeAttributes[attr].end=end;this.runtimeAttributes[attr].unit=(isset(attributes[attr].unit))?attributes[attr]['unit']:this.getDefaultUnit(attr);},init:function(el,attributes,duration,method){var isAnimated=false;var startTime=null;var actualFrames=0;el=YAHOO.util.Dom.get(el);this.attributes=attributes||{};this.duration=duration||1;this.method=method||YAHOO.util.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=YAHOO.util.AnimMgr.fps;this.getEl=function(){return el;};this.isAnimated=function(){return isAnimated;};this.getStartTime=function(){return startTime;};this.runtimeAttributes={};this.animate=function(){if(this.isAnimated()){return false;} -this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(YAHOO.util.AnimMgr.fps*this.duration):this.duration;YAHOO.util.AnimMgr.registerElement(this);};this.stop=function(finish){if(finish){this.currentFrame=this.totalFrames;this._onTween.fire();} -YAHOO.util.AnimMgr.stop(this);};var onStart=function(){this.onStart.fire();this.runtimeAttributes={};for(var attr in this.attributes){this.setRuntimeAttribute(attr);} -isAnimated=true;actualFrames=0;startTime=new Date();};var onTween=function(){var data={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};this.onTween.fire(data);var runtimeAttributes=this.runtimeAttributes;for(var attr in runtimeAttributes){this.setAttribute(attr,this.doMethod(attr,runtimeAttributes[attr].start,runtimeAttributes[attr].end),runtimeAttributes[attr].unit);} -actualFrames+=1;};var onComplete=function(){var actual_duration=(new Date()-startTime)/1000;var data={duration:actual_duration,frames:actualFrames,fps:actualFrames/actual_duration};isAnimated=false;actualFrames=0;this.onComplete.fire(data);};this._onStart=new YAHOO.util.CustomEvent('_start',this,true);this.onStart=new YAHOO.util.CustomEvent('start',this);this.onTween=new YAHOO.util.CustomEvent('tween',this);this._onTween=new YAHOO.util.CustomEvent('_tween',this,true);this.onComplete=new YAHOO.util.CustomEvent('complete',this);this._onComplete=new YAHOO.util.CustomEvent('_complete',this,true);this._onStart.subscribe(onStart);this._onTween.subscribe(onTween);this._onComplete.subscribe(onComplete);}};YAHOO.util.AnimMgr=new function(){var thread=null;var queue=[];var tweenCount=0;this.fps=1000;this.delay=1;this.registerElement=function(tween){queue[queue.length]=tween;tweenCount+=1;tween._onStart.fire();this.start();};this.unRegister=function(tween,index){tween._onComplete.fire();index=index||getIndex(tween);if(index!=-1){queue.splice(index,1);} -tweenCount-=1;if(tweenCount<=0){this.stop();}};this.start=function(){if(thread===null){thread=setInterval(this.run,this.delay);}};this.stop=function(tween){if(!tween){clearInterval(thread);for(var i=0,len=queue.length;i<len;++i){if(queue[i].isAnimated()){this.unRegister(tween,i);}} -queue=[];thread=null;tweenCount=0;} -else{this.unRegister(tween);}};this.run=function(){for(var i=0,len=queue.length;i<len;++i){var tween=queue[i];if(!tween||!tween.isAnimated()){continue;} -if(tween.currentFrame<tween.totalFrames||tween.totalFrames===null) -{tween.currentFrame+=1;if(tween.useSeconds){correctFrame(tween);} -tween._onTween.fire();} -else{YAHOO.util.AnimMgr.stop(tween,i);}}};var getIndex=function(anim){for(var i=0,len=queue.length;i<len;++i){if(queue[i]==anim){return i;}} -return-1;};var correctFrame=function(tween){var frames=tween.totalFrames;var frame=tween.currentFrame;var expected=(tween.currentFrame*tween.duration*1000/tween.totalFrames);var elapsed=(new Date()-tween.getStartTime());var tweak=0;if(elapsed<tween.duration*1000){tweak=Math.round((elapsed/expected-1)*tween.currentFrame);}else{tweak=frames-(frame+1);} -if(tweak>0&&isFinite(tweak)){if(tween.currentFrame+tweak>=frames){tweak=frames-(frame+1);} -tween.currentFrame+=tweak;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(points,t){var n=points.length;var tmp=[];for(var i=0;i<n;++i){tmp[i]=[points[i][0],points[i][1]];} -for(var j=1;j<n;++j){for(i=0;i<n-j;++i){tmp[i][0]=(1-t)*tmp[i][0]+t*tmp[parseInt(i+1,10)][0];tmp[i][1]=(1-t)*tmp[i][1]+t*tmp[parseInt(i+1,10)][1];}} -return[tmp[0][0],tmp[0][1]];};};(function(){YAHOO.util.ColorAnim=function(el,attributes,duration,method){YAHOO.util.ColorAnim.superclass.constructor.call(this,el,attributes,duration,method);};YAHOO.extend(YAHOO.util.ColorAnim,YAHOO.util.Anim);var Y=YAHOO.util;var superclass=Y.ColorAnim.superclass;var proto=Y.ColorAnim.prototype;proto.patterns.color=/color$/i;proto.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;proto.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;proto.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;proto.patterns.transparent=/^transparent|rgba\(0, 0, 0, 0\)$/;proto.parseColor=function(s){if(s.length==3){return s;} -var c=this.patterns.hex.exec(s);if(c&&c.length==4){return[parseInt(c[1],16),parseInt(c[2],16),parseInt(c[3],16)];} -c=this.patterns.rgb.exec(s);if(c&&c.length==4){return[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)];} -c=this.patterns.hex3.exec(s);if(c&&c.length==4){return[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)];} -return null;};proto.getAttribute=function(attr){var el=this.getEl();if(this.patterns.color.test(attr)){var val=YAHOO.util.Dom.getStyle(el,attr);if(this.patterns.transparent.test(val)){var parent=el.parentNode;val=Y.Dom.getStyle(parent,attr);while(parent&&this.patterns.transparent.test(val)){parent=parent.parentNode;val=Y.Dom.getStyle(parent,attr);if(parent.tagName.toUpperCase()=='HTML'){val='#fff';}}}}else{val=superclass.getAttribute.call(this,attr);} -return val;};proto.doMethod=function(attr,start,end){var val;if(this.patterns.color.test(attr)){val=[];for(var i=0,len=start.length;i<len;++i){val[i]=superclass.doMethod.call(this,attr,start[i],end[i]);} -val='rgb('+Math.floor(val[0])+','+Math.floor(val[1])+','+Math.floor(val[2])+')';} -else{val=superclass.doMethod.call(this,attr,start,end);} -return val;};proto.setRuntimeAttribute=function(attr){superclass.setRuntimeAttribute.call(this,attr);if(this.patterns.color.test(attr)){var attributes=this.attributes;var start=this.parseColor(this.runtimeAttributes[attr].start);var end=this.parseColor(this.runtimeAttributes[attr].end);if(typeof attributes[attr]['to']==='undefined'&&typeof attributes[attr]['by']!=='undefined'){end=this.parseColor(attributes[attr].by);for(var i=0,len=start.length;i<len;++i){end[i]=start[i]+end[i];}} -this.runtimeAttributes[attr].start=start;this.runtimeAttributes[attr].end=end;}};})();YAHOO.util.Easing={easeNone:function(t,b,c,d){return c*t/d+b;},easeIn:function(t,b,c,d){return c*(t/=d)*t+b;},easeOut:function(t,b,c,d){return-c*(t/=d)*(t-2)+b;},easeBoth:function(t,b,c,d){if((t/=d/2)<1){return c/2*t*t+b;} -return-c/2*((--t)*(t-2)-1)+b;},backIn:function(t,b,c,d,s){if(typeof s=='undefined'){s=1.70158;} -return c*(t/=d)*t*((s+1)*t-s)+b;},backOut:function(t,b,c,d,s){if(typeof s=='undefined'){s=1.70158;} -return c*((t=t/d-1)*t*((s+1)*t+s)+1)+b;},backBoth:function(t,b,c,d,s){if(typeof s=='undefined'){s=1.70158;} -if((t/=d/2)<1){return c/2*(t*t*(((s*=(1.525))+1)*t-s))+b;} -return c/2*((t-=2)*t*(((s*=(1.525))+1)*t+s)+2)+b;}}; -(function(){YAHOO.util.Motion=function(el,attributes,duration,method){if(el){YAHOO.util.Motion.superclass.constructor.call(this,el,attributes,duration,method);}};YAHOO.extend(YAHOO.util.Motion,YAHOO.util.ColorAnim);var Y=YAHOO.util;var superclass=Y.Motion.superclass;var proto=Y.Motion.prototype;proto.patterns.points=/^points$/i;proto.setAttribute=function(attr,val,unit){if(this.patterns.points.test(attr)){unit=unit||'px';superclass.setAttribute.call(this,'left',val[0],unit);superclass.setAttribute.call(this,'top',val[1],unit);}else{superclass.setAttribute.call(this,attr,val,unit);}};proto.getAttribute=function(attr){if(this.patterns.points.test(attr)){var val=[superclass.getAttribute.call(this,'left'),superclass.getAttribute.call(this,'top')];}else{val=superclass.getAttribute.call(this,attr);} -return val;};proto.doMethod=function(attr,start,end){var val=null;if(this.patterns.points.test(attr)){var t=this.method(this.currentFrame,0,100,this.totalFrames)/100;val=Y.Bezier.getPosition(this.runtimeAttributes[attr],t);}else{val=superclass.doMethod.call(this,attr,start,end);} -return val;};proto.setRuntimeAttribute=function(attr){if(this.patterns.points.test(attr)){var el=this.getEl();var attributes=this.attributes;var start;var control=attributes['points']['control']||[];var end;var i,len;if(control.length>0&&!(control[0]instanceof Array)){control=[control];}else{var tmp=[];for(i=0,len=control.length;i<len;++i){tmp[i]=control[i];} -control=tmp;} -if(Y.Dom.getStyle(el,'position')=='static'){Y.Dom.setStyle(el,'position','relative');} -if(isset(attributes['points']['from'])){Y.Dom.setXY(el,attributes['points']['from']);} -else{Y.Dom.setXY(el,Y.Dom.getXY(el));} -start=this.getAttribute('points');if(isset(attributes['points']['to'])){end=translateValues.call(this,attributes['points']['to'],start);var pageXY=Y.Dom.getXY(this.getEl());for(i=0,len=control.length;i<len;++i){control[i]=translateValues.call(this,control[i],start);}}else if(isset(attributes['points']['by'])){end=[start[0]+attributes['points']['by'][0],start[1]+attributes['points']['by'][1]];for(i=0,len=control.length;i<len;++i){control[i]=[start[0]+control[i][0],start[1]+control[i][1]];}} -this.runtimeAttributes[attr]=[start];if(control.length>0){this.runtimeAttributes[attr]=this.runtimeAttributes[attr].concat(control);} -this.runtimeAttributes[attr][this.runtimeAttributes[attr].length]=end;} -else{superclass.setRuntimeAttribute.call(this,attr);}};var translateValues=function(val,start){var pageXY=Y.Dom.getXY(this.getEl());val=[val[0]-pageXY[0]+start[0],val[1]-pageXY[1]+start[1]];return val;};var isset=function(prop){return(typeof prop!=='undefined');};})(); -(function(){var Event=YAHOO.util.Event;var Dom=YAHOO.util.Dom;YAHOO.util.DragDrop=function(id,sGroup,config){if(id){this.init(id,sGroup,config);}};YAHOO.util.DragDrop.prototype={id:null,config:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isTarget:true,padding:null,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryButtonOnly:true,available:false,hasOuterHandles:false,startDrag:function(x,y){},b4Drag:function(e){},onDrag:function(e){},onDragEnter:function(e,id){},onDragOver:function(e,id){},onDragOut:function(e,id){},onDragDrop:function(e,id){},onInvalidDrop:function(e){},endDrag:function(e){},b4MouseDown:function(e){},onMouseDown:function(e){},onMouseUp:function(e){},onAvailable:function(){},getEl:function(){if(!this._domRef){this._domRef=Dom.get(this.id);} -return this._domRef;},getDragEl:function(){return Dom.get(this.dragElId);},init:function(id,sGroup,config){this.initTarget(id,sGroup,config);Event.on(this.id,"mousedown",this.handleMouseDown,this,true);},initTarget:function(id,sGroup,config){this.config=config||{};this.DDM=YAHOO.util.DDM;this.groups={};if(typeof id!=="string"){id=Dom.generateId(id);} -this.id=id;this.addToGroup((sGroup)?sGroup:"default");this.handleElId=id;Event.onAvailable(id,this.handleOnAvailable,this,true);this.setDragElId(id);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();},applyConfig:function(){this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false);},handleOnAvailable:function(){this.available=true;this.resetConstraints();this.onAvailable();},setPadding:function(iTop,iRight,iBot,iLeft){if(!iRight&&0!==iRight){this.padding=[iTop,iTop,iTop,iTop];}else if(!iBot&&0!==iBot){this.padding=[iTop,iRight,iTop,iRight];}else{this.padding=[iTop,iRight,iBot,iLeft];}},setInitPosition:function(diffX,diffY){var el=this.getEl();if(!this.DDM.verifyEl(el)){return;} -var dx=diffX||0;var dy=diffY||0;var p=Dom.getXY(el);this.initPageX=p[0]-dx;this.initPageY=p[1]-dy;this.lastPageX=p[0];this.lastPageY=p[1];this.setStartPosition(p);},setStartPosition:function(pos){var p=pos||Dom.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=p[0];this.startPageY=p[1];},addToGroup:function(sGroup){this.groups[sGroup]=true;this.DDM.regDragDrop(this,sGroup);},removeFromGroup:function(sGroup){if(this.groups[sGroup]){delete this.groups[sGroup];} -this.DDM.removeDDFromGroup(this,sGroup);},setDragElId:function(id){this.dragElId=id;},setHandleElId:function(id){if(typeof id!=="string"){id=Dom.generateId(id);} -this.handleElId=id;this.DDM.regHandle(this.id,id);},setOuterHandleElId:function(id){if(typeof id!=="string"){id=Dom.generateId(id);} -Event.on(id,"mousedown",this.handleMouseDown,this,true);this.setHandleElId(id);this.hasOuterHandles=true;},unreg:function(){Event.removeListener(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this);},isLocked:function(){return(this.DDM.isLocked()||this.locked);},handleMouseDown:function(e,oDD){var button=e.which||e.button;if(this.primaryButtonOnly&&button>1){return;} -if(this.isLocked()){return;} -this.DDM.refreshCache(this.groups);var pt=new YAHOO.util.Point(Event.getPageX(e),Event.getPageY(e));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(pt,this)){}else{if(this.clickValidator(e)){this.setStartPosition();this.b4MouseDown(e);this.onMouseDown(e);this.DDM.handleMouseDown(e,this);this.DDM.stopEvent(e);}else{}}},clickValidator:function(e){var target=Event.getTarget(e);return(this.isValidHandleChild(target)&&(this.id==this.handleElId||this.DDM.handleWasClicked(target,this.id)));},addInvalidHandleType:function(tagName){var type=tagName.toUpperCase();this.invalidHandleTypes[type]=type;},addInvalidHandleId:function(id){if(typeof id!=="string"){id=Dom.generateId(id);} -this.invalidHandleIds[id]=id;},addInvalidHandleClass:function(cssClass){this.invalidHandleClasses.push(cssClass);},removeInvalidHandleType:function(tagName){var type=tagName.toUpperCase();delete this.invalidHandleTypes[type];},removeInvalidHandleId:function(id){if(typeof id!=="string"){id=Dom.generateId(id);} -delete this.invalidHandleIds[id];},removeInvalidHandleClass:function(cssClass){for(var i=0,len=this.invalidHandleClasses.length;i<len;++i){if(this.invalidHandleClasses[i]==cssClass){delete this.invalidHandleClasses[i];}}},isValidHandleChild:function(node){var valid=true;var nodeName;try{nodeName=node.nodeName.toUpperCase();}catch(e){nodeName=node.nodeName;} -valid=valid&&!this.invalidHandleTypes[nodeName];valid=valid&&!this.invalidHandleIds[node.id];for(var i=0,len=this.invalidHandleClasses.length;valid&&i<len;++i){valid=!Dom.hasClass(node,this.invalidHandleClasses[i]);} -return valid;},setXTicks:function(iStartX,iTickSize){this.xTicks=[];this.xTickSize=iTickSize;var tickMap={};for(var i=this.initPageX;i>=this.minX;i=i-iTickSize){if(!tickMap[i]){this.xTicks[this.xTicks.length]=i;tickMap[i]=true;}} -for(i=this.initPageX;i<=this.maxX;i=i+iTickSize){if(!tickMap[i]){this.xTicks[this.xTicks.length]=i;tickMap[i]=true;}} -this.xTicks.sort(this.DDM.numericSort);},setYTicks:function(iStartY,iTickSize){this.yTicks=[];this.yTickSize=iTickSize;var tickMap={};for(var i=this.initPageY;i>=this.minY;i=i-iTickSize){if(!tickMap[i]){this.yTicks[this.yTicks.length]=i;tickMap[i]=true;}} -for(i=this.initPageY;i<=this.maxY;i=i+iTickSize){if(!tickMap[i]){this.yTicks[this.yTicks.length]=i;tickMap[i]=true;}} -this.yTicks.sort(this.DDM.numericSort);},setXConstraint:function(iLeft,iRight,iTickSize){this.leftConstraint=iLeft;this.rightConstraint=iRight;this.minX=this.initPageX-iLeft;this.maxX=this.initPageX+iRight;if(iTickSize){this.setXTicks(this.initPageX,iTickSize);} -this.constrainX=true;},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks();},clearTicks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0;},setYConstraint:function(iUp,iDown,iTickSize){this.topConstraint=iUp;this.bottomConstraint=iDown;this.minY=this.initPageY-iUp;this.maxY=this.initPageY+iDown;if(iTickSize){this.setYTicks(this.initPageY,iTickSize);} -this.constrainY=true;},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var dx=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var dy=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(dx,dy);}else{this.setInitPosition();} -if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize);} -if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize);}},getTick:function(val,tickArray){if(!tickArray){return val;}else if(tickArray[0]>=val){return tickArray[0];}else{for(var i=0,len=tickArray.length;i<len;++i){var next=i+1;if(tickArray[next]&&tickArray[next]>=val){var diff1=val-tickArray[i];var diff2=tickArray[next]-val;return(diff2>diff1)?tickArray[i]:tickArray[next];}} -return tickArray[tickArray.length-1];}}};})(); -if(!YAHOO.util.DragDropMgr){YAHOO.util.DragDropMgr=function(){var Event=YAHOO.util.Event;return{ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initalized:false,locked:false,init:function(){this.initialized=true;},POINT:0,INTERSECT:1,STRICT_INTERSECT:2,mode:0,_execOnAll:function(sMethod,args){for(var i in this.ids){for(var j in this.ids[i]){var oDD=this.ids[i][j];if(!this.isTypeOfDD(oDD)){continue;} -oDD[sMethod].apply(oDD,args);}}},_onLoad:function(){this.init();Event.on(document,"mouseup",this.handleMouseUp,this,true);Event.on(document,"mousemove",this.handleMouseMove,this,true);Event.on(window,"unload",this._onUnload,this,true);Event.on(window,"resize",this._onResize,this,true);},_onResize:function(e){this._execOnAll("resetConstraints",[]);},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:1000,dragThreshMet:false,clickTimeout:null,startX:0,startY:0,regDragDrop:function(oDD,sGroup){if(!this.initialized){this.init();} -if(!this.ids[sGroup]){this.ids[sGroup]={};} -this.ids[sGroup][oDD.id]=oDD;},removeDDFromGroup:function(oDD,sGroup){if(!this.ids[sGroup]){this.ids[sGroup]={};} -var obj=this.ids[sGroup];if(obj&&obj[oDD.id]){delete obj[oDD.id];}},_remove:function(oDD){for(var g in oDD.groups){if(g&&this.ids[g][oDD.id]){delete this.ids[g][oDD.id];}} -delete this.handleIds[oDD.id];},regHandle:function(sDDId,sHandleId){if(!this.handleIds[sDDId]){this.handleIds[sDDId]={};} -this.handleIds[sDDId][sHandleId]=sHandleId;},isDragDrop:function(id){return(this.getDDById(id))?true:false;},getRelated:function(p_oDD,bTargetsOnly){var oDDs=[];for(var i in p_oDD.groups){for(j in this.ids[i]){var dd=this.ids[i][j];if(!this.isTypeOfDD(dd)){continue;} -if(!bTargetsOnly||dd.isTarget){oDDs[oDDs.length]=dd;}}} -return oDDs;},isLegalTarget:function(oDD,oTargetDD){var targets=this.getRelated(oDD,true);for(var i=0,len=targets.length;i<len;++i){if(targets[i].id==oTargetDD.id){return true;}} -return false;},isTypeOfDD:function(oDD){return(oDD&&oDD.__ygDragDrop);},isHandle:function(sDDId,sHandleId){return(this.handleIds[sDDId]&&this.handleIds[sDDId][sHandleId]);},getDDById:function(id){for(var i in this.ids){if(this.ids[i][id]){return this.ids[i][id];}} -return null;},handleMouseDown:function(e,oDD){this.currentTarget=YAHOO.util.Event.getTarget(e);this.dragCurrent=oDD;var el=oDD.getEl();this.startX=YAHOO.util.Event.getPageX(e);this.startY=YAHOO.util.Event.getPageY(e);this.deltaX=this.startX-el.offsetLeft;this.deltaY=this.startY-el.offsetTop;this.dragThreshMet=false;this.clickTimeout=setTimeout(function(){var DDM=YAHOO.util.DDM;DDM.startDrag(DDM.startX,DDM.startY);},this.clickTimeThresh);},startDrag:function(x,y){clearTimeout(this.clickTimeout);if(this.dragCurrent){this.dragCurrent.startDrag(x,y);} -this.dragThreshMet=true;},handleMouseUp:function(e){if(!this.dragCurrent){return;} -clearTimeout(this.clickTimeout);if(this.dragThreshMet){this.fireEvents(e,true);}else{} -this.stopDrag(e);/* MPS 2007-01-19 this.stopEvent(e); */},stopEvent:function(e){if(this.stopPropagation){YAHOO.util.Event.stopPropagation(e);} -if(this.preventDefault){YAHOO.util.Event.preventDefault(e);}},stopDrag:function(e){if(this.dragCurrent){if(this.dragThreshMet){this.dragCurrent.endDrag(e);} -this.dragCurrent.onMouseUp(e);} -this.dragCurrent=null;this.dragOvers={};},handleMouseMove:function(e){if(!this.dragCurrent){return true;} -if(YAHOO.util.Event.isIE&&!e.button){this.stopEvent(e);return this.handleMouseUp(e);} -if(!this.dragThreshMet){var diffX=Math.abs(this.startX-YAHOO.util.Event.getPageX(e));var diffY=Math.abs(this.startY-YAHOO.util.Event.getPageY(e));if(diffX>this.clickPixelThresh||diffY>this.clickPixelThresh){this.startDrag(this.startX,this.startY);}} -if(this.dragThreshMet){this.dragCurrent.b4Drag(e);this.dragCurrent.onDrag(e);this.fireEvents(e,false);} -this.stopEvent(e);return true;},fireEvents:function(e,isDrop){var dc=this.dragCurrent;if(!dc||dc.isLocked()){return;} -var x=YAHOO.util.Event.getPageX(e);var y=YAHOO.util.Event.getPageY(e);var pt=new YAHOO.util.Point(x,y);var oldOvers=[];var outEvts=[];var overEvts=[];var dropEvts=[];var enterEvts=[];for(var i in this.dragOvers){var ddo=this.dragOvers[i];if(!this.isTypeOfDD(ddo)){continue;} -if(!this.isOverTarget(pt,ddo,this.mode)){outEvts.push(ddo);} -oldOvers[i]=true;delete this.dragOvers[i];} -for(var sGroup in dc.groups){if("string"!=typeof sGroup){continue;} -for(i in this.ids[sGroup]){var oDD=this.ids[sGroup][i];if(!this.isTypeOfDD(oDD)){continue;} -if(oDD.isTarget&&!oDD.isLocked()&&oDD!=dc){if(this.isOverTarget(pt,oDD,this.mode)){if(isDrop){dropEvts.push(oDD);}else{if(!oldOvers[oDD.id]){enterEvts.push(oDD);}else{overEvts.push(oDD);} -this.dragOvers[oDD.id]=oDD;}}}}} -if(this.mode){if(outEvts.length){dc.onDragOut(e,outEvts);} -if(enterEvts.length){dc.onDragEnter(e,enterEvts);} -if(overEvts.length){dc.onDragOver(e,overEvts);} -if(dropEvts.length){dc.onDragDrop(e,dropEvts);}}else{var len=0;for(i=0,len=outEvts.length;i<len;++i){dc.onDragOut(e,outEvts[i].id);} -for(i=0,len=enterEvts.length;i<len;++i){dc.onDragEnter(e,enterEvts[i].id);} -for(i=0,len=overEvts.length;i<len;++i){dc.onDragOver(e,overEvts[i].id);} -for(i=0,len=dropEvts.length;i<len;++i){dc.onDragDrop(e,dropEvts[i].id);}} -if(isDrop&&!dropEvts.length){dc.onInvalidDrop(e);}},getBestMatch:function(dds){var winner=null;var len=dds.length;if(len==1){winner=dds[0];}else{for(var i=0;i<len;++i){var dd=dds[i];if(this.mode==this.INTERSECT&&dd.cursorIsOver){winner=dd;break;}else{if(!winner||!winner.overlap||(dd.overlap&&winner.overlap.getArea()<dd.overlap.getArea())){winner=dd;}}}} -return winner;},refreshCache:function(groups){for(var sGroup in groups){if("string"!=typeof sGroup){continue;} -for(var i in this.ids[sGroup]){var oDD=this.ids[sGroup][i];if(this.isTypeOfDD(oDD)){var loc=this.getLocation(oDD);if(loc){this.locationCache[oDD.id]=loc;}else{delete this.locationCache[oDD.id];}}}}},verifyEl:function(el){try{if(el){var parent=el.offsetParent;if(parent){return true;}}}catch(e){} -return false;},getLocation:function(oDD){if(!this.isTypeOfDD(oDD)){return null;} -var el=oDD.getEl(),pos,x1,x2,y1,y2,t,r,b,l;try{pos=YAHOO.util.Dom.getXY(el);}catch(e){} -if(!pos){return null;} -x1=pos[0];x2=x1+el.offsetWidth;y1=pos[1];y2=y1+el.offsetHeight;t=y1-oDD.padding[0];r=x2+oDD.padding[1];b=y2+oDD.padding[2];l=x1-oDD.padding[3];return new YAHOO.util.Region(t,r,b,l);},isOverTarget:function(pt,oTarget,intersect){var loc=this.locationCache[oTarget.id];if(!loc||!this.useCache){loc=this.getLocation(oTarget);this.locationCache[oTarget.id]=loc;} -if(!loc){return false;} -oTarget.cursorIsOver=loc.contains(pt);var dc=this.dragCurrent;if(!dc||!dc.getTargetCoord||(!intersect&&!dc.constrainX&&!dc.constrainY)){return oTarget.cursorIsOver;} -oTarget.overlap=null;var pos=dc.getTargetCoord(pt.x,pt.y);var el=dc.getDragEl();var curRegion=new YAHOO.util.Region(pos.y,pos.x+el.offsetWidth,pos.y+el.offsetHeight,pos.x);var overlap=curRegion.intersect(loc);if(overlap){oTarget.overlap=overlap;return(intersect)?true:oTarget.cursorIsOver;}else{return false;}},_onUnload:function(e,me){this.unregAll();},unregAll:function(){if(this.dragCurrent){this.stopDrag();this.dragCurrent=null;} -this._execOnAll("unreg",[]);for(i in this.elementCache){delete this.elementCache[i];} -this.elementCache={};this.ids={};},elementCache:{},getElWrapper:function(id){var oWrapper=this.elementCache[id];if(!oWrapper||!oWrapper.el){oWrapper=this.elementCache[id]=new this.ElementWrapper(YAHOO.util.Dom.get(id));} -return oWrapper;},getElement:function(id){return YAHOO.util.Dom.get(id);},getCss:function(id){var el=YAHOO.util.Dom.get(id);return(el)?el.style:null;},ElementWrapper:function(el){this.el=el||null;this.id=this.el&&el.id;this.css=this.el&&el.style;},getPosX:function(el){return YAHOO.util.Dom.getX(el);},getPosY:function(el){return YAHOO.util.Dom.getY(el);},swapNode:function(n1,n2){if(n1.swapNode){n1.swapNode(n2);}else{var p=n2.parentNode;var s=n2.nextSibling;if(s==n1){p.insertBefore(n1,n2);}else if(n2==n1.nextSibling){p.insertBefore(n2,n1);}else{n1.parentNode.replaceChild(n2,n1);p.insertBefore(n1,s);}}},getScroll:function(){var t,l,dde=document.documentElement,db=document.body;if(dde&&(dde.scrollTop||dde.scrollLeft)){t=dde.scrollTop;l=dde.scrollLeft;}else if(db){t=db.scrollTop;l=db.scrollLeft;} -return{top:t,left:l};},getStyle:function(el,styleProp){return YAHOO.util.Dom.getStyle(el,styleProp);},getScrollTop:function(){return this.getScroll().top;},getScrollLeft:function(){return this.getScroll().left;},moveToEl:function(moveEl,targetEl){var aCoord=YAHOO.util.Dom.getXY(targetEl);YAHOO.util.Dom.setXY(moveEl,aCoord);},getClientHeight:function(){return YAHOO.util.Dom.getViewportHeight();},getClientWidth:function(){return YAHOO.util.Dom.getViewportWidth();},numericSort:function(a,b){return(a-b);},_timeoutCount:0,_addListeners:function(){var DDM=YAHOO.util.DDM;if(YAHOO.util.Event&&document){DDM._onLoad();}else{if(DDM._timeoutCount>2000){}else{setTimeout(DDM._addListeners,10);if(document&&document.body){DDM._timeoutCount+=1;}}}},handleWasClicked:function(node,id){if(this.isHandle(id,node.id)){return true;}else{var p=node.parentNode;while(p){if(this.isHandle(id,p.id)){return true;}else{p=p.parentNode;}}} -return false;}};}();YAHOO.util.DDM=YAHOO.util.DragDropMgr;YAHOO.util.DDM._addListeners();} -YAHOO.util.DD=function(id,sGroup,config){if(id){this.init(id,sGroup,config);}};YAHOO.extend(YAHOO.util.DD,YAHOO.util.DragDrop,{scroll:true,autoOffset:function(iPageX,iPageY){var x=iPageX-this.startPageX;var y=iPageY-this.startPageY;this.setDelta(x,y);},setDelta:function(iDeltaX,iDeltaY){this.deltaX=iDeltaX;this.deltaY=iDeltaY;},setDragElPos:function(iPageX,iPageY){var el=this.getDragEl();this.alignElWithMouse(el,iPageX,iPageY);},alignElWithMouse:function(el,iPageX,iPageY){var oCoord=this.getTargetCoord(iPageX,iPageY);if(!this.deltaSetXY){var aCoord=[oCoord.x,oCoord.y];YAHOO.util.Dom.setXY(el,aCoord);var newLeft=parseInt(YAHOO.util.Dom.getStyle(el,"left"),10);var newTop=parseInt(YAHOO.util.Dom.getStyle(el,"top"),10);this.deltaSetXY=[newLeft-oCoord.x,newTop-oCoord.y];}else{YAHOO.util.Dom.setStyle(el,"left",(oCoord.x+this.deltaSetXY[0])+"px");YAHOO.util.Dom.setStyle(el,"top",(oCoord.y+this.deltaSetXY[1])+"px");} -this.cachePosition(oCoord.x,oCoord.y);this.autoScroll(oCoord.x,oCoord.y,el.offsetHeight,el.offsetWidth);},cachePosition:function(iPageX,iPageY){if(iPageX){this.lastPageX=iPageX;this.lastPageY=iPageY;}else{var aCoord=YAHOO.util.Dom.getXY(this.getEl());this.lastPageX=aCoord[0];this.lastPageY=aCoord[1];}},autoScroll:function(x,y,h,w){if(this.scroll){var clientH=this.DDM.getClientHeight();var clientW=this.DDM.getClientWidth();var st=this.DDM.getScrollTop();var sl=this.DDM.getScrollLeft();var bot=h+y;var right=w+x;var toBot=(clientH+st-y-this.deltaY);var toRight=(clientW+sl-x-this.deltaX);var thresh=40;var scrAmt=(document.all)?80:30;if(bot>clientH&&toBot<thresh){window.scrollTo(sl,st+scrAmt);} -if(y<st&&st>0&&y-st<thresh){window.scrollTo(sl,st-scrAmt);} -if(right>clientW&&toRight<thresh){window.scrollTo(sl+scrAmt,st);} -if(x<sl&&sl>0&&x-sl<thresh){window.scrollTo(sl-scrAmt,st);}}},getTargetCoord:function(iPageX,iPageY){var x=iPageX-this.deltaX;var y=iPageY-this.deltaY;if(this.constrainX){if(x<this.minX){x=this.minX;} -if(x>this.maxX){x=this.maxX;}} -if(this.constrainY){if(y<this.minY){y=this.minY;} -if(y>this.maxY){y=this.maxY;}} -x=this.getTick(x,this.xTicks);y=this.getTick(y,this.yTicks);return{x:x,y:y};},applyConfig:function(){YAHOO.util.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false);},b4MouseDown:function(e){this.autoOffset(YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e));},b4Drag:function(e){this.setDragElPos(YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e));}}); |