aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App/Controller/Report
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Report')
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm128
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/Update.pm52
2 files changed, 132 insertions, 48 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm
index fc1a78cd5..f64a109e8 100644
--- a/perllib/FixMyStreet/App/Controller/Report/New.pm
+++ b/perllib/FixMyStreet/App/Controller/Report/New.pm
@@ -6,8 +6,7 @@ BEGIN { extends 'Catalyst::Controller'; }
use utf8;
use Encode;
-use List::MoreUtils qw(uniq);
-use List::Util 'first';
+use List::Util qw(uniq);
use HTML::Entities;
use Path::Class;
use Utils;
@@ -30,8 +29,8 @@ Create a new report, or complete a partial one.
submit_problem: true if a problem has been submitted, at all.
submit_sign_in: true if the sign in button has been clicked by logged out user.
-submit_register: true if the register/confirm by email button has been clicked
-by logged out user.
+submit_register(_mobile): true if the register/confirm by email button has been clicked
+by logged out user, or submit button clicked by logged in user.
=head2 location (required)
@@ -127,8 +126,10 @@ sub report_new_ajax : Path('mobile') : Args(0) {
# Apps are sending email as username
# Prepare for when they upgrade
- if (!$c->get_param('username')) {
- $c->set_param('username', $c->get_param('email'));
+ my $username_field = ( $c->get_param('submit_sign_in') || $c->get_param('password_sign_in') )
+ ? 'username': 'username_register';
+ if (!$c->get_param($username_field)) {
+ $c->set_param($username_field, $c->get_param('email'));
}
# create the report - loading a partial if available
@@ -333,12 +334,14 @@ sub disable_form_message : Private {
my %category;
foreach my $opt (@{$_->{values}}) {
if ($opt->{disable}) {
- $category{message} = $opt->{disable_message} || $_->{datatype_description};
- $category{code} = $_->{code};
- push @{$category{answers}}, $opt->{key};
+ my $message = $opt->{disable_message} || $_->{datatype_description};
+ $category{$message} ||= {};
+ $category{$message}->{message} = $message;
+ $category{$message}->{code} = $_->{code};
+ push @{$category{$message}->{answers}}, $opt->{key};
}
}
- push @{$out{questions}}, \%category if %category;
+ push @{$out{questions}}, $_ for values %category;
}
}
@@ -759,14 +762,20 @@ sub setup_categories_and_bodies : Private {
if !$c->stash->{unresponsive}{ALL} &&
($contact->email =~ /^REFUSED$/i || $body_send_method eq 'Refused');
- push @category_options, $contact unless $seen{$contact->category};
- $seen{$contact->category} = $contact;
+ if (my $cat = $seen{$contact->category}) {
+ # Make sure the category is listed in all its groups, not just the first set
+ my @groups = uniq @{$cat->groups}, @{$contact->groups};
+ $cat->set_extra_metadata(group => \@groups);
+ } else {
+ push @category_options, $contact;
+ $seen{$contact->category} = $contact;
+ }
}
if (@category_options) {
# If there's an Other category present, put it at the bottom
@category_options = (
- { category => _('-- Pick a category --'), category_display => _('-- Pick a category --'), group => '' },
+ { category => _('-- Pick a category --'), category_display => _('-- Pick a category --'), group => [''] },
grep { $_->category ne _('Other') } @category_options );
push @category_options, $seen{_('Other')} if $seen{_('Other')};
}
@@ -837,10 +846,16 @@ sub process_user : Private {
# Extract all the params to a hash to make them easier to work with
my %params = map { $_ => $c->get_param($_) }
- ( 'email', 'name', 'phone', 'password_register', 'fms_extra_title' );
+ qw( email name phone password_register fms_extra_title update_method );
- # Report form includes two username fields: #form_username_register and #form_username_sign_in
- $params{username} = (first { $_ } $c->get_param_list('username')) || '';
+ if ($c->user_exists) {
+ $params{username} = $c->get_param('username');
+ } elsif ($c->get_param('submit_sign_in') || $c->get_param('password_sign_in')) {
+ $params{username} = $c->get_param('username');
+ } else {
+ $params{username} = $c->get_param('username_register');
+ }
+ $params{username} ||= '';
my $anon_button = $c->cobrand->allow_anonymous_reports eq 'button' && $c->get_param('report_anonymously');
my $anon_fallback = $c->cobrand->allow_anonymous_reports eq '1' && !$c->user_exists && !$params{username};
@@ -891,11 +906,24 @@ sub process_user : Private {
$params{username} = $params{phone};
}
+ # Code to deal with SMS being switched on and so the user being asked to
+ # pick a method and no username field
+ if (!$params{username} && !$params{update_method}) {
+ $c->stash->{field_errors}->{update_method} = _('Please pick your update preference');
+ }
+ if (!$params{username} && $params{update_method}) {
+ if ($params{update_method} eq 'phone') {
+ $params{username} = $params{phone};
+ } else {
+ $params{username} = $params{email};
+ }
+ $c->stash->{update_method} = $params{update_method};
+ }
+
my $parsed = FixMyStreet::SMS->parse_username($params{username});
my $type = $parsed->{type} || 'email';
$type = 'email' unless FixMyStreet->config('SMS_AUTHENTICATION') || $c->stash->{contributing_as_another_user};
- $report->user( $c->model('DB::User')->find_or_new( { $type => $parsed->{username} } ) )
- unless $report->user;
+ $report->user( $c->model('DB::User')->find_or_new( { $type => $parsed->{username} } ) );
$c->stash->{phone_may_be_mobile} = $type eq 'phone' && $parsed->{may_be_mobile};
@@ -1018,7 +1046,13 @@ sub process_report : Private {
$report->detail( $detail );
# mobile device type
- $report->service( $params{service} ) if $params{service};
+ if ($params{service}) {
+ $report->service($params{service});
+ } elsif ($c->get_param('submit_register_mobile')) {
+ $report->service('mobile');
+ } elsif ($c->get_param('submit_register')) {
+ $report->service('desktop');
+ }
# set these straight from the params
$report->category( _ $params{category} ) if $params{category};
@@ -1106,7 +1140,7 @@ sub process_report : Private {
# save the cobrand and language related information
$report->cobrand( $c->cobrand->moniker );
- $report->cobrand_data( '' );
+ $report->cobrand_data( $c->stash->{cobrand_data} || '' );
$report->lang( $c->stash->{lang_code} );
return 1;
@@ -1228,6 +1262,7 @@ sub check_for_errors : Private {
# if using social login then we don't care about other errors
$c->stash->{is_social_user} = $c->get_param('social_sign_in') ? 1 : 0;
if ( $c->stash->{is_social_user} ) {
+ delete $field_errors{update_method};
delete $field_errors{name};
delete $field_errors{username};
}
@@ -1243,6 +1278,16 @@ sub check_for_errors : Private {
$field_errors{photo} = $photo_error;
}
+ # Now assign the username error according to where it came from
+ if ($field_errors{username}) {
+ if ($c->get_param('submit_sign_in') || $c->get_param('password_sign_in')) {
+ $field_errors{username_sign_in} = $field_errors{username};
+ } else {
+ $field_errors{username_register} = $field_errors{username};
+ }
+ delete $field_errors{username};
+ }
+
# all good if no errors
return 1 unless scalar keys %field_errors || $c->stash->{login_success};
@@ -1301,6 +1346,11 @@ sub send_problem_confirm_text : Private {
$data->{id} = $report->id;
$c->forward('/auth/phone/send_token', [ $data, 'problem', $report->user->phone ]);
+ my $error = $c->render_fragment( 'auth/_username_error.html', { default => 'phone' });
+ if ($error) {
+ $c->stash->{field_errors}{phone} = $error;
+ $c->forward('generate_map');
+ }
$c->stash->{submit_url} = '/report/new/text';
}
@@ -1626,7 +1676,7 @@ sub redirect_or_confirm_creation : Private {
$c->forward( 'create_related_things' );
if ($c->stash->{contributing_as_another_user} && $report->user->email
&& $report->user->id != $c->user->id
- && !$c->cobrand->report_sent_confirmation_email) {
+ && !$c->cobrand->report_sent_confirmation_email($report)) {
$c->send_email( 'other-reported.txt', {
to => [ [ $report->user->email, $report->name ] ],
} );
@@ -1674,21 +1724,8 @@ sub create_related_things : Private {
foreach my $body (values %{$problem->bodies}) {
my $user = $body->comment_user or next;
- my %open311_conf = (
- endpoint => $body->endpoint || '',
- api_key => $body->api_key || '',
- jurisdiction => $body->jurisdiction || '',
- extended_statuses => $body->send_extended_statuses,
- );
-
- my $cobrand = $body->get_cobrand_handler;
- $cobrand->call_hook(open311_config_updates => \%open311_conf)
- if $cobrand;
-
- my $open311 = Open311->new(%open311_conf);
my $updates = Open311::GetServiceRequestUpdates->new(
system_user => $user,
- current_open311 => $open311,
current_body => $body,
blank_updates_permitted => 1,
);
@@ -1699,7 +1736,10 @@ sub create_related_things : Private {
my $request = {
service_request_id => $problem->id,
update_id => 'auto-internal',
- comment_time => DateTime->now,
+ # Add a second so it is definitely later than problem confirmed timestamp,
+ # which uses current_timestamp (and thus microseconds) whilst this update
+ # is rounded down to the nearest second
+ comment_time => DateTime->now->add( seconds => 1 ),
status => 'open',
description => $description,
};
@@ -1793,6 +1833,24 @@ sub generate_category_extra_json : Private {
return \@fields;
}
+sub non_map_creation : Private {
+ my ($self, $c, $extras) = @_;
+
+ $c->forward('initialize_report');
+ $c->forward('check_for_category');
+ $c->forward('/auth/check_csrf_token');
+ $c->forward('process_report');
+ $c->forward('process_user');
+ if ($extras) {
+ $c->forward($_) for @$extras;
+ }
+ $c->forward('/photo/process_photo');
+ return 0 unless $c->forward('check_for_errors');
+ $c->forward('save_user_and_report');
+ return 1;
+
+}
+
__PACKAGE__->meta->make_immutable;
1;
diff --git a/perllib/FixMyStreet/App/Controller/Report/Update.pm b/perllib/FixMyStreet/App/Controller/Report/Update.pm
index 41c42b8a1..2acafc654 100644
--- a/perllib/FixMyStreet/App/Controller/Report/Update.pm
+++ b/perllib/FixMyStreet/App/Controller/Report/Update.pm
@@ -6,7 +6,6 @@ BEGIN { extends 'Catalyst::Controller'; }
use utf8;
use Path::Class;
-use List::Util 'first';
use Utils;
=head1 NAME
@@ -103,8 +102,14 @@ sub process_user : Private {
my %params = map { $_ => $c->get_param($_) }
( 'name', 'password_register', 'fms_extra_title' );
- # Update form includes two username fields: #form_username_register and #form_username_sign_in
- $params{username} = (first { $_ } $c->get_param_list('username')) || '';
+ if ($c->user_exists) {
+ $params{username} = $c->get_param('username');
+ } elsif ($c->get_param('submit_sign_in') || $c->get_param('password_sign_in')) {
+ $params{username} = $c->get_param('username');
+ } else {
+ $params{username} = $c->get_param('username_register');
+ }
+ $params{username} ||= '';
my $anon_button = $c->cobrand->allow_anonymous_reports eq 'button' && $c->get_param('report_anonymously');
if ($anon_button) {
@@ -121,7 +126,7 @@ sub process_user : Private {
if ( $c->user_exists ) { {
my $user = $c->user->obj;
- if ($c->stash->{contributing_as_another_user} = $user->contributing_as('another_user', $c, $update->problem->bodies_str_ids)) {
+ if ($c->stash->{contributing_as_another_user} = $user->contributing_as('another_user', $c, $c->stash->{problem}->bodies_str_ids)) {
# Act as if not logged in (and it will be auto-confirmed later on)
last;
}
@@ -145,8 +150,7 @@ sub process_user : Private {
my $parsed = FixMyStreet::SMS->parse_username($params{username});
my $type = $parsed->{type} || 'email';
$type = 'email' unless FixMyStreet->config('SMS_AUTHENTICATION') || $c->stash->{contributing_as_another_user};
- $update->user( $c->model('DB::User')->find_or_new( { $type => $parsed->{username} } ) )
- unless $update->user;
+ $update->user( $c->model('DB::User')->find_or_new( { $type => $parsed->{username} } ) );
$c->stash->{phone_may_be_mobile} = $type eq 'phone' && $parsed->{may_be_mobile};
@@ -248,7 +252,7 @@ sub load_problem : Private {
# Problem ID could come from existing update in token, or from query parameter
my $problem_id = $update->problem_id || $c->get_param('id');
$c->forward( '/report/load_problem_or_display_error', [ $problem_id ] );
- $update->problem($c->stash->{problem});
+ $update->problem_id($c->stash->{problem}->id);
}
=head2 check_form_submitted
@@ -282,7 +286,8 @@ sub process_update : Private {
my $name = Utils::trim_text( $params{name} );
- $params{reopen} = 0 unless $c->user && $c->user->id == $c->stash->{problem}->user->id;
+ my $problem = $c->stash->{problem};
+ $params{reopen} = 0 unless $c->user && $c->user->id == $problem->user->id;
my $update = $c->stash->{update};
$update->text($params{update});
@@ -290,11 +295,11 @@ sub process_update : Private {
$update->mark_fixed($params{fixed} ? 1 : 0);
$update->mark_open($params{reopen} ? 1 : 0);
- $c->stash->{contributing_as_body} = $c->user_exists && $c->user->contributing_as('body', $c, $update->problem->bodies_str_ids);
- $c->stash->{contributing_as_anonymous_user} = $c->user_exists && $c->user->contributing_as('anonymous_user', $c, $update->problem->bodies_str_ids);
+ $c->stash->{contributing_as_body} = $c->user_exists && $c->user->contributing_as('body', $c, $problem->bodies_str_ids);
+ $c->stash->{contributing_as_anonymous_user} = $c->user_exists && $c->user->contributing_as('anonymous_user', $c, $problem->bodies_str_ids);
# This is also done in process_user, but is needed here for anonymous() just below
- my $anon_button = $c->cobrand->allow_anonymous_reports($update->problem->category) eq 'button' && $c->get_param('report_anonymously');
+ my $anon_button = $c->cobrand->allow_anonymous_reports($problem->category) eq 'button' && $c->get_param('report_anonymously');
if ($anon_button) {
$c->stash->{contributing_as_anonymous_user} = 1;
$c->stash->{contributing_as_body} = undef;
@@ -323,7 +328,6 @@ sub process_update : Private {
# then we are not changing the state of the problem so can use the current
# problem state
} else {
- my $problem = $c->stash->{problem} || $update->problem;
$update->problem_state( $problem->state );
}
}
@@ -332,7 +336,7 @@ sub process_update : Private {
my @extra; # Next function fills this, but we don't need it here.
# This is just so that the error checking for these extra fields runs.
# TODO Use extra here as it is used on reports.
- my $body = (values %{$update->problem->bodies})[0];
+ my $body = (values %{$problem->bodies})[0];
$c->cobrand->process_open311_extras( $c, $body, \@extra );
if ( $c->get_param('fms_extra_title') ) {
@@ -404,6 +408,16 @@ sub check_for_errors : Private {
$field_errors{photo} = $photo_error;
}
+ # Now assign the username error according to where it came from
+ if ($field_errors{username}) {
+ if ($c->get_param('submit_sign_in') || $c->get_param('password_sign_in')) {
+ $field_errors{username_sign_in} = $field_errors{username};
+ } else {
+ $field_errors{username_register} = $field_errors{username};
+ }
+ delete $field_errors{username};
+ }
+
# all good if no errors
return 1
unless ( scalar keys %field_errors
@@ -484,6 +498,13 @@ sub save_update : Private {
$update->confirm();
} elsif ($c->stash->{contributing_as_anonymous_user}) {
$update->set_extra_metadata( contributed_as => 'anonymous_user' );
+ if ( $c->user_exists && $c->user->from_body ) {
+ # If a staff user has clicked the 'report anonymously' button then
+ # there would be no record of who that staff member was as we've
+ # used the cobrand's anonymous_account for the report. In this case
+ # record the staff user ID in the report metadata.
+ $update->set_extra_metadata( contributed_by => $c->user->id );
+ }
$update->confirm();
} elsif ( !$update->user->in_storage ) {
# User does not exist.
@@ -571,6 +592,11 @@ sub send_confirmation_text : Private {
my ( $self, $c ) = @_;
my $update = $c->stash->{update};
$c->forward('/auth/phone/send_token', [ $c->stash->{token_data}, 'comment', $update->user->phone ]);
+ my $error = $c->render_fragment( 'auth/_username_error.html', { default => 'phone' });
+ if ($error) {
+ $c->stash->{field_errors}{username_register} = $error;
+ $c->go( '/report/display', [ $c->stash->{problem}->id ], [] );
+ }
$c->stash->{submit_url} = '/report/update/text';
}