aboutsummaryrefslogtreecommitdiffstats
path: root/perllib
diff options
context:
space:
mode:
Diffstat (limited to 'perllib')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin/Bodies.pm328
-rw-r--r--perllib/FixMyStreet/App/Controller/My.pm2
-rw-r--r--perllib/FixMyStreet/Cobrand/BathNES.pm13
-rw-r--r--perllib/FixMyStreet/Cobrand/Bexley.pm5
-rw-r--r--perllib/FixMyStreet/DB/Result/Contact.pm2
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm23
-rw-r--r--perllib/FixMyStreet/Roles/Translatable.pm13
7 files changed, 211 insertions, 175 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin/Bodies.pm b/perllib/FixMyStreet/App/Controller/Admin/Bodies.pm
index fa5a55213..165fdc783 100644
--- a/perllib/FixMyStreet/App/Controller/Admin/Bodies.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin/Bodies.pm
@@ -51,27 +51,7 @@ sub index : Path : Args(0) {
my $posted = $c->get_param('posted') || '';
if ( $posted eq 'body' ) {
- $c->forward('check_for_super_user');
- $c->forward('/auth/check_csrf_token');
-
- my $values = $c->forward('body_params');
- unless ( keys %{$c->stash->{body_errors}} ) {
- my $body = $c->model('DB::Body')->create( $values->{params} );
- if ($values->{extras}) {
- $body->set_extra_metadata( $_ => $values->{extras}->{$_} )
- for keys %{$values->{extras}};
- $body->update;
- }
- my @area_ids = $c->get_param_list('area_ids');
- foreach (@area_ids) {
- $c->model('DB::BodyArea')->create( { body => $body, area_id => $_ } );
- }
-
- $c->stash->{object} = $body;
- $c->stash->{translation_col} = 'name';
- $c->forward('update_translations');
- $c->stash->{updated} = _('New body added');
- }
+ $c->forward('update_body', [ undef, _('New body added') ]);
}
$c->forward( '/admin/fetch_all_bodies' );
@@ -158,7 +138,8 @@ sub category : Chained('body') : PathPart('') {
$c->forward( '/auth/get_csrf_token' );
my $contact = $c->stash->{body}->contacts->search( { category => $category } )->first;
- $c->stash->{contact} = $contact;
+ $c->detach( '/page_error_404_not_found', [] ) unless $contact;
+ $c->stash->{contact} = $c->stash->{current_contact} = $contact;
$c->stash->{translation_col} = 'category';
$c->stash->{object} = $c->stash->{contact};
@@ -220,161 +201,197 @@ sub check_for_super_user : Private {
sub update_contacts : Private {
my ( $self, $c ) = @_;
- my $posted = $c->get_param('posted');
- my $editor = $c->forward('/admin/get_user');
-
+ my $posted = $c->get_param('posted') || '';
if ( $posted eq 'new' ) {
- $c->forward('/auth/check_csrf_token');
+ $c->forward('update_contact');
+ } elsif ( $posted eq 'update' ) {
+ $c->forward('confirm_contacts');
+ } elsif ( $posted eq 'body' ) {
+ $c->forward('update_body', [ $c->stash->{body}, _('Values updated') ]);
+ }
+}
- my %errors;
+sub update_contact : Private {
+ my ( $self, $c ) = @_;
- my $category = $self->trim( $c->get_param('category') );
- $errors{category} = _("Please choose a category") unless $category;
- $errors{note} = _('Please enter a message') unless $c->get_param('note');
+ my $editor = $c->forward('/admin/get_user');
+ $c->forward('/auth/check_csrf_token');
- my $contact = $c->model('DB::Contact')->find_or_new(
- {
- body_id => $c->stash->{body_id},
- category => $category,
- }
- );
+ my %errors;
- my $email = $c->get_param('email');
- $email =~ s/\s+//g;
- my $send_method = $c->get_param('send_method') || $contact->body->send_method || "";
- unless ( $send_method eq 'Open311' ) {
- $errors{email} = _('Please enter a valid email') unless is_valid_email_list($email) || $email eq 'REFUSED';
- }
+ my $current_category = $c->get_param('current_category') || '';
+ my $current_contact = $c->model('DB::Contact')->find({
+ body_id => $c->stash->{body_id},
+ category => $current_category,
+ });
+ $c->stash->{current_contact} = $current_contact;
- $contact->email( $email );
- $contact->state( $c->get_param('state') );
- $contact->non_public( $c->get_param('non_public') ? 1 : 0 );
- $contact->note( $c->get_param('note') );
- $contact->whenedited( \'current_timestamp' );
- $contact->editor( $editor );
- $contact->endpoint( $c->get_param('endpoint') );
- $contact->jurisdiction( $c->get_param('jurisdiction') );
- $contact->api_key( $c->get_param('api_key') );
- $contact->send_method( $c->get_param('send_method') );
-
- # Set flags in extra to the appropriate values
- if ( $c->get_param('photo_required') ) {
- $contact->set_extra_metadata_if_undefined( photo_required => 1 );
- }
- else {
- $contact->unset_extra_metadata( 'photo_required' );
- }
- if ( $c->get_param('inspection_required') ) {
- $contact->set_extra_metadata( inspection_required => 1 );
- }
- else {
- $contact->unset_extra_metadata( 'inspection_required' );
- }
- if ( $c->get_param('reputation_threshold') ) {
- $contact->set_extra_metadata( reputation_threshold => int($c->get_param('reputation_threshold')) );
- }
- if ( my @group = $c->get_param_list('group') ) {
- @group = grep { $_ } @group;
- if (scalar @group == 0) {
- $contact->unset_extra_metadata( 'group' );
- } else {
- $contact->set_extra_metadata( group => \@group );
- }
- } else {
- $contact->unset_extra_metadata( 'group' );
+ my $category = $self->trim( $c->get_param('category') );
+ $errors{category} = _("Please choose a category") unless $category;
+ $errors{note} = _('Please enter a message') unless $c->get_param('note') || FixMyStreet->config('STAGING_SITE');
+
+ my $contact = $c->model('DB::Contact')->find_or_new(
+ {
+ body_id => $c->stash->{body_id},
+ category => $category,
}
+ );
+ if ($current_contact && $contact->id && $contact->id != $current_contact->id) {
+ $errors{category} = _('You cannot rename a category to an existing category');
+ } elsif ($current_contact && !$contact->id) {
+ # Changed name
+ $contact = $current_contact;
+ $c->model('DB::Problem')->to_body($c->stash->{body_id})->search({ category => $current_category })->update({ category => $category });
+ $contact->category($category);
+ }
+ my $email = $c->get_param('email');
+ $email =~ s/\s+//g;
+ my $send_method = $c->get_param('send_method') || $contact->body->send_method || "";
+ unless ( $send_method eq 'Open311' ) {
+ $errors{email} = _('Please enter a valid email') unless is_valid_email_list($email) || $email eq 'REFUSED';
+ }
- $c->forward('/admin/update_extra_fields', [ $contact ]);
- $c->forward('contact_cobrand_extra_fields', [ $contact ]);
-
- # Special form disabling form
- if ($c->get_param('disable')) {
- my $msg = $c->get_param('disable_message');
- $errors{category} = _('Please enter a message') unless $msg;
- my $meta = {
- code => '_fms_disable_',
- variable => 'false',
- protected => 'true',
- disable_form => 'true',
- description => $msg,
- };
- $contact->update_extra_field($meta);
+ $contact->email( $email );
+ $contact->state( $c->get_param('state') );
+ $contact->non_public( $c->get_param('non_public') ? 1 : 0 );
+ $contact->note( $c->get_param('note') );
+ $contact->whenedited( \'current_timestamp' );
+ $contact->editor( $editor );
+ $contact->endpoint( $c->get_param('endpoint') );
+ $contact->jurisdiction( $c->get_param('jurisdiction') );
+ $contact->api_key( $c->get_param('api_key') );
+ $contact->send_method( $c->get_param('send_method') );
+
+ # Set flags in extra to the appropriate values
+ if ( $c->get_param('photo_required') ) {
+ $contact->set_extra_metadata_if_undefined( photo_required => 1 );
+ } else {
+ $contact->unset_extra_metadata( 'photo_required' );
+ }
+ if ( $c->get_param('inspection_required') ) {
+ $contact->set_extra_metadata( inspection_required => 1 );
+ } else {
+ $contact->unset_extra_metadata( 'inspection_required' );
+ }
+ if ( $c->get_param('reputation_threshold') ) {
+ $contact->set_extra_metadata( reputation_threshold => int($c->get_param('reputation_threshold')) );
+ }
+ if ( my @group = $c->get_param_list('group') ) {
+ @group = grep { $_ } @group;
+ if (scalar @group == 0) {
+ $contact->unset_extra_metadata( 'group' );
} else {
- $contact->remove_extra_field('_fms_disable_');
+ $contact->set_extra_metadata( group => \@group );
}
+ } else {
+ $contact->unset_extra_metadata( 'group' );
+ }
- if ( %errors ) {
- $c->stash->{updated} = _('Please correct the errors below');
- $c->stash->{contact} = $contact;
- $c->stash->{errors} = \%errors;
- } elsif ( $contact->in_storage ) {
- $c->stash->{updated} = _('Values updated');
- # NB: History is automatically stored by a trigger in the database
- $contact->update;
- } else {
- $c->stash->{updated} = _('New category contact added');
- $contact->insert;
+ $c->forward('/admin/update_extra_fields', [ $contact ]);
+ $c->forward('contact_cobrand_extra_fields', [ $contact, \%errors ]);
+
+ # Special form disabling form
+ if ($c->get_param('disable')) {
+ my $msg = $c->get_param('disable_message');
+ $errors{category} = _('Please enter a message') unless $msg;
+ my $meta = {
+ code => '_fms_disable_',
+ variable => 'false',
+ protected => 'true',
+ disable_form => 'true',
+ description => $msg,
+ };
+ $contact->update_extra_field($meta);
+ } else {
+ $contact->remove_extra_field('_fms_disable_');
+ }
+
+ if ( %errors ) {
+ $c->stash->{updated} = _('Please correct the errors below');
+ $c->stash->{contact} = $contact;
+ $c->stash->{errors} = \%errors;
+ } elsif ( $contact->in_storage ) {
+ $c->stash->{updated} = _('Values updated');
+
+ # NB: History is automatically stored by a trigger in the database
+ $contact->update;
+ } else {
+ $c->stash->{updated} = _('New category contact added');
+ $contact->insert;
+ }
+
+ unless ( %errors ) {
+ $c->stash->{translation_col} = 'category';
+ $c->stash->{object} = $contact;
+ $c->forward('update_translations');
+ }
+
+}
+
+sub confirm_contacts : Private {
+ my ( $self, $c ) = @_;
+
+ $c->forward('/auth/check_csrf_token');
+
+ my @categories = $c->get_param_list('confirmed');
+
+ my $contacts = $c->model('DB::Contact')->search(
+ {
+ body_id => $c->stash->{body_id},
+ category => { -in => \@categories },
}
+ );
- unless ( %errors ) {
- $c->stash->{translation_col} = 'category';
- $c->stash->{object} = $contact;
- $c->forward('update_translations');
+ my $editor = $c->forward('/admin/get_user');
+ $contacts->update(
+ {
+ state => 'confirmed',
+ whenedited => \'current_timestamp',
+ note => 'Confirmed',
+ editor => $editor,
}
+ );
- } elsif ( $posted eq 'update' ) {
- $c->forward('/auth/check_csrf_token');
+ $c->stash->{updated} = _('Values updated');
+}
- my @categories = $c->get_param_list('confirmed');
+sub update_body : Private {
+ my ($self, $c, $body, $msg) = @_;
- my $contacts = $c->model('DB::Contact')->search(
- {
- body_id => $c->stash->{body_id},
- category => { -in => \@categories },
- }
- );
-
- $contacts->update(
- {
- state => 'confirmed',
- whenedited => \'current_timestamp',
- note => 'Confirmed',
- editor => $editor,
- }
- );
+ $c->forward('check_for_super_user');
+ $c->forward('/auth/check_csrf_token');
- $c->stash->{updated} = _('Values updated');
- } elsif ( $posted eq 'body' ) {
- $c->forward('check_for_super_user');
- $c->forward('/auth/check_csrf_token');
-
- my $values = $c->forward( 'body_params' );
- unless ( keys %{$c->stash->{body_errors}} ) {
- $c->stash->{body}->update( $values->{params} );
- if ($values->{extras}) {
- $c->stash->{body}->set_extra_metadata( $_ => $values->{extras}->{$_} )
- for keys %{$values->{extras}};
- $c->stash->{body}->update;
- }
- my @current = $c->stash->{body}->body_areas->all;
- my %current = map { $_->area_id => 1 } @current;
- my @area_ids = $c->get_param_list('area_ids');
- foreach (@area_ids) {
- $c->model('DB::BodyArea')->find_or_create( { body => $c->stash->{body}, area_id => $_ } );
- delete $current{$_};
- }
- # Remove any others
- $c->stash->{body}->body_areas->search( { area_id => [ keys %current ] } )->delete;
+ my $values = $c->forward('body_params');
+ return if %{$c->stash->{body_errors}};
- $c->stash->{translation_col} = 'name';
- $c->stash->{object} = $c->stash->{body};
- $c->forward('update_translations');
+ if ($body) {
+ $body->update( $values->{params} );
+ } else {
+ $body = $c->model('DB::Body')->create( $values->{params} );
+ }
- $c->stash->{updated} = _('Values updated');
- }
+ if ($values->{extras}) {
+ $body->set_extra_metadata( $_ => $values->{extras}->{$_} )
+ for keys %{$values->{extras}};
+ $body->update;
}
+ my @current = $body->body_areas->all;
+ my %current = map { $_->area_id => 1 } @current;
+ my @area_ids = $c->get_param_list('area_ids');
+ foreach (@area_ids) {
+ $c->model('DB::BodyArea')->find_or_create( { body => $body, area_id => $_ } );
+ delete $current{$_};
+ }
+ # Remove any others
+ $body->body_areas->search( { area_id => [ keys %current ] } )->delete;
+
+ $c->stash->{translation_col} = 'name';
+ $c->stash->{object} = $body;
+ $c->forward('update_translations');
+
+ $c->stash->{updated} = $msg;
}
sub body_params : Private {
@@ -417,12 +434,13 @@ sub check_body_params : Private {
}
sub contact_cobrand_extra_fields : Private {
- my ( $self, $c, $contact ) = @_;
+ my ( $self, $c, $contact, $errors ) = @_;
my $extra_fields = $c->cobrand->call_hook('contact_extra_fields');
foreach ( @$extra_fields ) {
$contact->set_extra_metadata( $_ => $c->get_param("extra[$_]") );
}
+ $c->cobrand->call_hook(contact_extra_fields_validation => $contact, $errors);
}
sub fetch_translations : Private {
diff --git a/perllib/FixMyStreet/App/Controller/My.pm b/perllib/FixMyStreet/App/Controller/My.pm
index ed890ad82..b181acd04 100644
--- a/perllib/FixMyStreet/App/Controller/My.pm
+++ b/perllib/FixMyStreet/App/Controller/My.pm
@@ -161,7 +161,7 @@ sub setup_page_data : Private {
my @categories = $c->stash->{problems_rs}->search({
state => [ FixMyStreet::DB::Result::Problem->visible_states() ],
}, {
- columns => [ 'category' ],
+ columns => [ 'category', 'bodies_str' ],
distinct => 1,
order_by => [ 'category' ],
} )->all;
diff --git a/perllib/FixMyStreet/Cobrand/BathNES.pm b/perllib/FixMyStreet/Cobrand/BathNES.pm
index b6014a276..6de28bca8 100644
--- a/perllib/FixMyStreet/Cobrand/BathNES.pm
+++ b/perllib/FixMyStreet/Cobrand/BathNES.pm
@@ -27,6 +27,19 @@ sub get_geocoder {
return 'OSM'; # default of Bing gives poor results, let's try overriding.
}
+sub contact_extra_fields { [ 'display_name' ] }
+
+sub contact_extra_fields_validation {
+ my ($self, $contact, $errors) = @_;
+ return unless $contact->get_extra_metadata('display_name');
+
+ my @contacts = $contact->body->contacts->not_deleted->search({ id => { '!=', $contact->id } });
+ my %display_names = map { $_->get_extra_metadata('display_name') => 1 } @contacts;
+ if ($display_names{$contact->get_extra_metadata('display_name')}) {
+ $errors->{display_name} = 'That display name is already in use';
+ }
+}
+
sub disambiguate_location {
my $self = shift;
my $string = shift;
diff --git a/perllib/FixMyStreet/Cobrand/Bexley.pm b/perllib/FixMyStreet/Cobrand/Bexley.pm
index 0fbb8944b..1a303d633 100644
--- a/perllib/FixMyStreet/Cobrand/Bexley.pm
+++ b/perllib/FixMyStreet/Cobrand/Bexley.pm
@@ -31,10 +31,7 @@ sub open311_munge_update_params {
$params->{service_request_id_ext} = $comment->problem->id;
- my $contact = $comment->result_source->schema->resultset("Contact")->not_deleted->find({
- body_id => $body->id,
- category => $comment->problem->category
- });
+ my $contact = $comment->problem->category_row;
$params->{service_code} = $contact->email;
}
diff --git a/perllib/FixMyStreet/DB/Result/Contact.pm b/perllib/FixMyStreet/DB/Result/Contact.pm
index a99915fb4..d8695683c 100644
--- a/perllib/FixMyStreet/DB/Result/Contact.pm
+++ b/perllib/FixMyStreet/DB/Result/Contact.pm
@@ -95,7 +95,7 @@ __PACKAGE__->many_to_many( defect_types => 'contact_defect_types', 'defect_type'
sub category_display {
my $self = shift;
- $self->translate_column('category');
+ $self->get_extra_metadata('display_name') || $self->translate_column('category');
}
sub groups {
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm
index 08b768719..97f0666e0 100644
--- a/perllib/FixMyStreet/DB/Result/Problem.pm
+++ b/perllib/FixMyStreet/DB/Result/Problem.pm
@@ -404,7 +404,28 @@ sub confirm {
sub category_display {
my $self = shift;
- $self->translate_column('category');
+ my $contact = $self->category_row;
+ return $self->category unless $contact; # Fallback; shouldn't happen, but some tests
+ return $contact->category_display;
+}
+
+=head2 category_row
+
+Returns the corresponding Contact object for this problem's category and body.
+If the report was sent to multiple bodies, only returns the first.
+
+=cut
+
+sub category_row {
+ my $self = shift;
+ my $schema = $self->result_source->schema;
+ my $body_id = $self->bodies_str_ids->[0];
+ return unless $body_id && $body_id =~ /^[0-9]+$/;
+ my $contact = $schema->resultset("Contact")->find({
+ body_id => $body_id,
+ category => $self->category,
+ });
+ return $contact;
}
sub bodies_str_ids {
diff --git a/perllib/FixMyStreet/Roles/Translatable.pm b/perllib/FixMyStreet/Roles/Translatable.pm
index d39d97bf8..0c84bbf0f 100644
--- a/perllib/FixMyStreet/Roles/Translatable.pm
+++ b/perllib/FixMyStreet/Roles/Translatable.pm
@@ -40,19 +40,6 @@ sub _translate {
my $translated = $self->translated->{$col}{$lang};
return $translated if $translated;
- # Deal with the fact problem table has denormalized copy of category string
- if ($table eq 'problem' && $col eq 'category') {
- my $body_id = $self->bodies_str_ids->[0];
- return $fallback unless $body_id && $body_id =~ /^[0-9]+$/;
- my $contact = $schema->resultset("Contact")->find( {
- body_id => $body_id,
- category => $fallback,
- } );
- return $fallback unless $contact; # Shouldn't happen, but some tests
- $table = 'contact';
- $id = $contact->id;
- }
-
if (ref $schema) {
my $translation = $schema->resultset('Translation')->find({
lang => $lang,