diff options
Diffstat (limited to 'perllib')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 42 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin/ReportExtraFields.pm | 61 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 33 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Default.pm | 15 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/ReportExtraFields.pm | 45 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm | 25 |
6 files changed, 221 insertions, 0 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index aab114576..cd1246134 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -375,6 +375,8 @@ sub update_contacts : Private { $contact->set_extra_metadata( reputation_threshold => int($c->get_param('reputation_threshold')) ); } + $c->forward('update_extra_fields', [ $contact ]); + if ( %errors ) { $c->stash->{updated} = _('Please correct the errors below'); $c->stash->{contact} = $contact; @@ -1973,6 +1975,46 @@ sub fetch_body_areas : Private { $c->stash->{fetched_areas_body_id} = $body->id; } +sub update_extra_fields : Private { + my ($self, $c, $object) = @_; + + my @indices = grep { /^metadata\[\d+\]\.code/ } keys %{ $c->req->params }; + @indices = sort map { /(\d+)/ } @indices; + + my @extra_fields; + foreach my $i (@indices) { + my $meta = {}; + $meta->{code} = $c->get_param("metadata[$i].code"); + next unless $meta->{code}; + $meta->{order} = int $c->get_param("metadata[$i].order"); + $meta->{datatype} = $c->get_param("metadata[$i].datatype"); + my $required = $c->get_param("metadata[$i].required") && $c->get_param("metadata[$i].required") eq 'on'; + $meta->{required} = $required ? 'true' : 'false'; + my $notice = $c->get_param("metadata[$i].notice") && $c->get_param("metadata[$i].notice") eq 'on'; + $meta->{variable} = $notice ? 'false' : 'true'; + $meta->{description} = $c->get_param("metadata[$i].description"); + $meta->{datatype_description} = $c->get_param("metadata[$i].datatype_description"); + + if ( $meta->{datatype} eq "singlevaluelist" ) { + $meta->{values} = []; + my $re = qr{^metadata\[$i\]\.values\[\d+\]\.key}; + my @vindices = grep { /$re/ } keys %{ $c->req->params }; + @vindices = sort map { /values\[(\d+)\]/ } @vindices; + foreach my $j (@vindices) { + my $name = $c->get_param("metadata[$i].values[$j].name"); + my $key = $c->get_param("metadata[$i].values[$j].key"); + push(@{$meta->{values}}, { + name => $name, + key => $key, + }) if $name; + } + } + push @extra_fields, $meta; + } + @extra_fields = sort { $a->{order} <=> $b->{order} } @extra_fields; + $object->set_extra_fields(@extra_fields); +} + sub trim { my $self = shift; my $e = shift; diff --git a/perllib/FixMyStreet/App/Controller/Admin/ReportExtraFields.pm b/perllib/FixMyStreet/App/Controller/Admin/ReportExtraFields.pm new file mode 100644 index 000000000..d5ec64698 --- /dev/null +++ b/perllib/FixMyStreet/App/Controller/Admin/ReportExtraFields.pm @@ -0,0 +1,61 @@ +package FixMyStreet::App::Controller::Admin::ReportExtraFields; +use Moose; +use namespace::autoclean; +use List::MoreUtils qw(uniq); + +BEGIN { extends 'Catalyst::Controller'; } + + +sub begin : Private { + my ( $self, $c ) = @_; + + $c->forward('/admin/begin'); +} + +sub index : Path : Args(0) { + my ( $self, $c ) = @_; + + my @extras = $c->model('DB::ReportExtraFields')->search( + undef, + { + order_by => 'name' + } + ); + + $c->stash->{extra_fields} = \@extras; +} + +sub edit : Path : Args(1) { + my ( $self, $c, $extra_id ) = @_; + + my $extra; + if ( $extra_id eq 'new' ) { + $extra = $c->model('DB::ReportExtraFields')->new({}); + } else { + $extra = $c->model('DB::ReportExtraFields')->find( $extra_id ) + or $c->detach( '/page_error_404_not_found' ); + } + + if ($c->req->method eq 'POST') { + $c->forward('/auth/check_csrf_token'); + + foreach (qw/name cobrand language/) { + $extra->$_($c->get_param($_)); + } + $c->forward('/admin/update_extra_fields', [ $extra ]); + + $extra->update_or_insert; + } + + $c->forward('/auth/get_csrf_token'); + $c->forward('/admin/fetch_languages'); + + my @cobrands = uniq sort map { $_->{moniker} } FixMyStreet::Cobrand->available_cobrand_classes; + $c->stash->{cobrands} = \@cobrands; + + $c->stash->{extra} = $extra; +} + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index a8d5b995e..00fe7dd7a 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -99,6 +99,7 @@ sub report_new : Path : Args(0) { # create a problem from the submitted details $c->stash->{template} = "report/new/fill_in_details.html"; $c->forward('setup_categories_and_bodies'); + $c->forward('setup_report_extra_fields'); $c->forward('generate_map'); $c->forward('check_for_category'); @@ -138,6 +139,7 @@ sub report_new_ajax : Path('mobile') : Args(0) { } $c->forward('setup_categories_and_bodies'); + $c->forward('setup_report_extra_fields'); $c->forward('process_user'); $c->forward('process_report'); $c->forward('/photo/process_photo'); @@ -185,6 +187,7 @@ sub report_form_ajax : Path('ajax') : Args(0) { } $c->forward('setup_categories_and_bodies'); + $c->forward('setup_report_extra_fields'); # render templates to get the html my $category = $c->render_fragment( 'report/new/category.html'); @@ -235,6 +238,7 @@ sub category_extras_ajax : Path('category_extras') : Args(0) { return 1; } $c->forward('setup_categories_and_bodies'); + $c->forward('setup_report_extra_fields'); $c->forward('check_for_category'); my $category = $c->stash->{category} || ""; @@ -254,6 +258,9 @@ sub category_extras_ajax : Path('category_extras') : Args(0) { if ($c->stash->{unresponsive}->{$category}) { $generate = 1; } + if ($c->stash->{report_extra_fields}) { + $generate = 1; + } if ($generate) { $category_extra = $c->render_fragment('report/new/category_extras.html', $vars); } @@ -689,6 +696,15 @@ sub setup_categories_and_bodies : Private { $c->stash->{missing_details_body_names} = \@missing_details_body_names; } +sub setup_report_extra_fields : Private { + my ( $self, $c ) = @_; + + return unless $c->cobrand->allow_report_extra_fields; + + my @extras = $c->model('DB::ReportExtraFields')->for_cobrand($c->cobrand)->for_language($c->stash->{lang_code})->all; + $c->stash->{report_extra_fields} = \@extras; +} + =head2 check_form_submitted $bool = $c->forward('check_form_submitted'); @@ -946,6 +962,23 @@ sub set_report_extras : Private { } } + foreach my $extra_fields (@{ $c->stash->{report_extra_fields} }) { + my $metas = $extra_fields->get_extra_fields; + $param_prefix = "extra[" . $extra_fields->id . "]"; + foreach my $field ( @$metas ) { + if ( lc( $field->{required} ) eq 'true' && !$c->cobrand->category_extra_hidden($field->{code})) { + unless ( $c->get_param($param_prefix . $field->{code}) ) { + $c->stash->{field_errors}->{ $field->{code} } = _('This information is required'); + } + } + push @extra, { + name => $field->{code}, + description => $field->{description}, + value => $c->get_param($param_prefix . $field->{code}) || '', + }; + } + } + $c->cobrand->process_open311_extras( $c, @$contacts[0]->body, \@extra ) if ( scalar @$contacts ); diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index 852f380f0..5dcdc9a4b 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -668,6 +668,10 @@ sub admin_pages { $pages->{users} = [ _('Users'), 6 ]; $pages->{user_edit} = [ undef, undef ]; } + if ( $self->allow_report_extra_fields && $user->has_body_permission_to('category_edit') ) { + $pages->{reportextrafields} = [ _('Extra Fields'), 10 ]; + $pages->{reportextrafields_edit} = [ undef, undef ]; + } return $pages; } @@ -1221,5 +1225,16 @@ the 'n days ago' format is used. By default the absolute date is always used. =cut sub display_days_ago_threshold { 0 } +=head2 allow_report_extra_fields + +Used to control whether site-wide extra fields are available. If true, +users with the category_edit permission can add site-wide fields via the +admin. + +=cut + +sub allow_report_extra_fields { 0 } + + 1; diff --git a/perllib/FixMyStreet/DB/Result/ReportExtraFields.pm b/perllib/FixMyStreet/DB/Result/ReportExtraFields.pm new file mode 100644 index 000000000..27a6bd2c6 --- /dev/null +++ b/perllib/FixMyStreet/DB/Result/ReportExtraFields.pm @@ -0,0 +1,45 @@ +use utf8; +package FixMyStreet::DB::Result::ReportExtraFields; + +# Created by DBIx::Class::Schema::Loader +# DO NOT MODIFY THE FIRST PART OF THIS FILE + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; +__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn"); +__PACKAGE__->table("report_extra_fields"); +__PACKAGE__->add_columns( + "id", + { + data_type => "integer", + is_auto_increment => 1, + is_nullable => 0, + sequence => "report_extra_fields_id_seq", + }, + "name", + { data_type => "text", is_nullable => 0 }, + "cobrand", + { data_type => "text", is_nullable => 1 }, + "language", + { data_type => "text", is_nullable => 1 }, + "extra", + { data_type => "text", is_nullable => 1 }, +); +__PACKAGE__->set_primary_key("id"); + + +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-07-28 09:51:34 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LkfbsUInnEyXowdcCEPjUQ + +__PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn"); +__PACKAGE__->rabx_column('extra'); + +use Moo; +use namespace::clean -except => [ 'meta' ]; + +with 'FixMyStreet::Roles::Extra'; + +# You can replace this text with custom code or comments, and it will be preserved on regeneration +1; diff --git a/perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm b/perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm new file mode 100644 index 000000000..1348df3c2 --- /dev/null +++ b/perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm @@ -0,0 +1,25 @@ +package FixMyStreet::DB::ResultSet::ReportExtraFields; +use base 'DBIx::Class::ResultSet'; + +use strict; +use warnings; + +sub for_cobrand { + my ( $rs, $cobrand ) = @_; + + my $result = $rs->search( + { cobrand => [ undef, $cobrand->moniker, '' ] } + ); + return $result; +} + +sub for_language { + my ( $rs, $language ) = @_; + + my $result = $rs->search( + { language => [ undef, $language, '' ] } + ); + return $result; +} + +1; |