diff options
Diffstat (limited to 'perllib/FixMyStreet/App/Controller')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Around.pm | 3 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/JSON.pm | 114 | ||||
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Questionnaire.pm | 228 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report.pm | 7 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 7 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Tokens.pm | 20 |
6 files changed, 366 insertions, 13 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm index 86e2ac001..cc7e84706 100644 --- a/perllib/FixMyStreet/App/Controller/Around.pm +++ b/perllib/FixMyStreet/App/Controller/Around.pm @@ -218,6 +218,7 @@ sub display_location : Private { if mySociety::Config::get('COUNTRY') eq 'GB'; $map_links .= "</p>"; + $c->stash->{map_links} = $map_links; $c->stash->{map_html} = FixMyStreet::Map::display_map( $c->fake_q, @@ -225,9 +226,7 @@ sub display_location : Private { longitude => $longitude, type => 1, pins => \@pins, - post => $map_links ); - $c->stash->{map_end_html} = FixMyStreet::Map::display_map_end(1); $c->stash->{map_js} = FixMyStreet::Map::header_js(); } diff --git a/perllib/FixMyStreet/App/Controller/JSON.pm b/perllib/FixMyStreet/App/Controller/JSON.pm new file mode 100644 index 000000000..c437aafc0 --- /dev/null +++ b/perllib/FixMyStreet/App/Controller/JSON.pm @@ -0,0 +1,114 @@ +package FixMyStreet::App::Controller::JSON; +use Moose; +use namespace::autoclean; + +BEGIN { extends 'Catalyst::Controller'; } + +use JSON; +use DateTime; +use DateTime::Format::ISO8601; + +=head1 NAME + +FixMyStreet::App::Controller::JSON - Catalyst Controller + +=head1 DESCRIPTION + +Provide information as JSON + +=head1 METHODS + +=head2 json + +=cut + +sub json : Path : Args(0) { + my ( $self, $c ) = @_; + + # gather the parameters + my $type = $c->req->param('type') || ''; + my $start_date = $c->req->param('start_date') || ''; + my $end_date = $c->req->param('end_date') || ''; + + my $yyyy_mm_dd = qr{^\d{4}-\d\d-\d\d$}; + if ( $start_date !~ $yyyy_mm_dd + || $end_date !~ $yyyy_mm_dd ) + { + $c->stash->{error} = 'Invalid dates supplied'; + return; + } + + # convert the dates to datetimes and trap errors + my $iso8601 = DateTime::Format::ISO8601->new; + my $start_dt = eval { $iso8601->parse_datetime($start_date); }; + my $end_dt = eval { $iso8601->parse_datetime($end_date); }; + unless ( $start_dt && $end_dt ) { + $c->stash->{error} = 'Invalid dates supplied'; + return; + } + + # check that the dates are sane + if ( $start_dt > $end_dt ) { + $c->stash->{error} = 'Start date after end date'; + return; + } + + # check that the type is supported + unless ( $type eq 'new_problems' || $type eq 'fixed_problems' ) { + $c->stash->{error} = 'Invalid type supplied'; + return; + } + + # query the database + $c->stash->{response} = + $type eq 'new_problems' + ? Problems::created_in_interval( $start_date, $end_date ) + : Problems::fixed_in_interval( $start_date, $end_date ); +} + +# If we convert this code to be fully DBIC based then the following snippet is a +# good start. The roadblock to doing it fully is the 'site_restriction' in the +# SQL which is currently provided as SQL, rather than something that could be +# easily added to the DBIC query. The hardest cobrand to change would be the +# cities - so perhaps do it after we know wether that needs to be kept or not. +# +# my $state = +# $type eq 'new_problems' ? 'confirmed' +# : $type eq 'fixed_problems' ? 'fixed_problems' +# : die; +# +# my $one_day = DateTime::Duration->new( days => 1 ); +# +# my $problems = $c->model('DB::Problem')->search( +# { +# created => { +# '>=' => $start_dt, +# '<=' => $end_dt + $one_day, +# }, +# state => $state, +# # ------ add is site_restriction here ------- +# }, +# { +# columns => [ +# 'id', 'title', 'council', 'category', +# 'detail', 'name', 'anonymous', 'confirmed', +# 'whensent', 'service', +# ] +# } +# ); + +sub end : Private { + my ( $self, $c ) = @_; + + my $response = + $c->stash->{error} + ? { error => $c->stash->{error} } + : $c->stash->{response}; + + $c->res->content_type('application/json; charset=utf-8'); + $c->res->body( encode_json( $response || {} ) ); +} + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/perllib/FixMyStreet/App/Controller/Questionnaire.pm b/perllib/FixMyStreet/App/Controller/Questionnaire.pm new file mode 100755 index 000000000..986543e9d --- /dev/null +++ b/perllib/FixMyStreet/App/Controller/Questionnaire.pm @@ -0,0 +1,228 @@ +package FixMyStreet::App::Controller::Questionnaire; + +use Moose; +use namespace::autoclean; +#use Utils; +#use Error qw(:try); +#use CrossSell; +#use mySociety::Locale; + +BEGIN { extends 'Catalyst::Controller'; } + +=head1 NAME + +FixMyStreet::App::Controller::Questionnaire - Catalyst Controller + +=head1 DESCRIPTION + +Catalyst Controller. + +=head1 METHODS + +=cut + +sub load_questionnaire : Private { + my ( $self, $c ) = @_; + + my $questionnaire = $c->model('DB::Questionnaire')->find( + { id => $c->stash->{id} }, + { prefetch => 'problem' } + ); + $c->stash->{questionnaire} = $questionnaire; + + my $problem_id = $questionnaire->problem_id; + + if ( $questionnaire->whenanswered ) { + my $problem_url = $c->uri_for( "/report/$problem_id" ); + my $contact_url = $c->uri_for( "/contact" ); + $c->stash->{message} = 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); + $c->stash->{template} = 'questionnaire/error.html'; + $c->detach; + } + + # FIXME problem fetched information + # extract(epoch from confirmed) as time, extract(epoch from whensent-confirmed) as whensent + # state in ('confirmed','fixed') + $c->stash->{problem} = $questionnaire->problem; + # throw Error::Simple(_("I'm afraid we couldn't locate your problem in the database.\n")) unless $problem; + + $c->stash->{answered_ever_reported} = $c->model('DB::Questionnaire')->count( + { 'problem.user_id' => $c->stash->{problem}->user_id, + ever_reported => { '!=', undef }, + }, + { join => 'problem' } + ); +} + +sub submit : Path('submit') { + my ( $self, $c ) = @_; + + $c->forward( '/tokens/load_questionnaire_id', [ $c->req->params->{token} ] ); + $c->forward( 'load_questionnaire' ); + + my $questionnaire = $c->stash->{questionnaire}; + my $problem = $questionnaire->problem; + + $c->stash->{num_questionnaire} = $c->model('DB::Questionnaire')->count( + { problem_id => $problem->id } + ); + + map { $c->stash->{$_} = $c->req->params->{$_} || '' } qw(been_fixed reported another update); + # EHA questionnaires done for you + if ($c->cobrand->moniker eq 'emptyhomes') { + $c->stash->{another} = $c->stash->{num_questionnaire}==1 ? 'Yes' : 'No'; + } + + my @errors; + push @errors, _('Please state whether or not the problem has been fixed') unless $c->stash->{been_fixed}; + my $ask_ever_reported = $c->cobrand->ask_ever_reported; + if ($ask_ever_reported) { + push @errors, _('Please say whether you\'ve ever reported a problem to your council before') unless $c->stash->{reported} || $c->stash->{answered_ever_reported}; + } + push @errors, _('Please indicate whether you\'d like to receive another questionnaire') + if ($c->stash->{been_fixed} eq 'No' || $c->stash->{been_fixed} eq 'Unknown') && !$c->stash->{another}; + push @errors, _('Please provide some explanation as to why you\'re reopening this report') + if $c->stash->{been_fixed} eq 'No' && $problem->state eq 'fixed' && !$c->stash->{update}; + if (@errors) { + $c->stash->{errors} = [ @errors ]; + $c->detach( 'display' ); + } + +# 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, $c->cobrand->extra_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, $c->cobrand->extra_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; +} + +# Sent here from email token action. Simply load and display questionnaire. +sub index : Private { + my ( $self, $c ) = @_; + $c->forward( 'load_questionnaire' ); + $c->forward( 'display' ); +} + +# Displays the questionnaire, either after bad submission or from email token +sub display : Private { + my ( $self, $c ) = @_; + + $c->stash->{template} = 'questionnaire/index.html'; + + my $problem = $c->stash->{questionnaire}->problem; + + my $problem_text = ''; # Page::display_problem_text($c->fake_q, $problem); # FIXME This needs to be in the template + $c->stash->{updates} = ''; # FIXME Should be database ResultSet of problem's pdates + $c->stash->{map_start_html} = FixMyStreet::Map::display_map( + $c->fake_q, + latitude => $problem->latitude, + longitude => $problem->longitude, + pins => [ [ $problem->latitude, $problem->longitude, $problem->state eq 'fixed' ? 'green' : 'red' ] ], + pre => $problem_text, + ); + $c->stash->{map_js} = FixMyStreet::Map::header_js(); + $c->stash->{cobrand_form_elements} = $c->cobrand->form_elements('questionnaireForm'); +} + +=head1 AUTHOR + +Matthew Somerville + +=head1 LICENSE + +Copyright (c) 2011 UK Citizens Online Democracy. All rights reserved. +Licensed under the Affero GPL. + +=cut + +__PACKAGE__->meta->make_immutable; + +1; + diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 0b235a06e..9041fa731 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -157,7 +157,7 @@ sub format_problem_for_display : Private { $c->stash->{banner} = $c->cobrand->generate_problem_banner($problem); - $c->stash->{allow_photo_upload} = $c->cobrand->allow_photo_display; + $c->stash->{allow_photo_upload} = $c->cobrand->allow_photo_display; # FIXME? $c->stash->{cobrand_alert_fields} = $c->cobrand->form_elements( '/alerts' ); $c->stash->{cobrand_update_fields} = $c->cobrand->form_elements( '/updateForm' ); @@ -187,7 +187,6 @@ sub format_problem_for_display : Private { sub generate_map_tags : Private { my ( $self, $c ) = @_; - my $map_links = ''; my $problem = $c->stash->{problem}; my ( $short_lat, $short_lon ) = @@ -196,7 +195,7 @@ sub generate_map_tags : Private { my $google_link = $c->cobrand->base_url_for_emails() . '/report/' . $problem->id; - $map_links = + $c->stash->{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 ) @@ -211,9 +210,7 @@ sub generate_map_tags : Private { pins => $problem->used_map ? [ [ $problem->latitude, $problem->longitude, 'blue' ] ] : [], - post => $map_links ); - $c->stash->{map_end_html} = FixMyStreet::Map::display_map_end(0), $c->stash->{map_js} = FixMyStreet::Map::header_js(); return 1; diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index 4c2264c9f..5a33718da 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -621,7 +621,7 @@ sub process_report : Private { $report->latitude( $c->stash->{latitude} ); $report->longitude( $c->stash->{longitude} ); - # Capture wether the may was used + # Capture whether the may was used $report->used_map( $params{skipped} ? 0 : 1 ); # Short circuit unless the form has been submitted @@ -918,7 +918,7 @@ sub generate_map : Private { <input type="hidden" name="pc" value="$pc"> <input type="hidden" name="skipped" value="1"> $cobrand_form_elements -<div id="skipped-map"> +<div> END_MAP_HTML } @@ -934,9 +934,6 @@ END_MAP_HTML ); } - # get the closing for the map - $c->stash->{map_end} = FixMyStreet::Map::display_map_end(1); - return 1; } diff --git a/perllib/FixMyStreet/App/Controller/Tokens.pm b/perllib/FixMyStreet/App/Controller/Tokens.pm index 1c3d89b54..7053edc95 100644 --- a/perllib/FixMyStreet/App/Controller/Tokens.pm +++ b/perllib/FixMyStreet/App/Controller/Tokens.pm @@ -156,6 +156,24 @@ sub confirm_update : Path('/C') { return 1; } +sub load_questionnaire_id : Private { + my ( $self, $c, $token_code ) = @_; + + # Set up error handling + $c->stash->{error_template} = 'questionnaire/error.html'; + $c->stash->{message} = _("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"); + + my $auth_token = $c->forward( 'load_auth_token', [ $token_code, 'questionnaire' ] ); + $c->stash->{id} = $auth_token->data; + $c->stash->{token} = $token_code; +} + +sub questionnaire : Path('/Q') : Args(1) { + my ( $self, $c, $token_code ) = @_; + $c->forward( 'load_questionnaire_id', [ $token_code ] ); + $c->forward( '/questionnaire/index'); +} + =head2 load_auth_token my $auth_token = @@ -193,7 +211,7 @@ Display an error page saying that there is something wrong with the token. sub token_error : Private { my ( $self, $c ) = @_; - $c->stash->{template} = 'tokens/error.html'; + $c->stash->{template} = $c->stash->{error_template} || 'tokens/error.html'; $c->detach; } |