aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App/Controller
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/App/Controller')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm81
-rw-r--r--perllib/FixMyStreet/App/Controller/Contact.pm4
-rw-r--r--perllib/FixMyStreet/App/Controller/Dashboard.pm126
-rwxr-xr-xperllib/FixMyStreet/App/Controller/FakeMapit.pm4
-rw-r--r--perllib/FixMyStreet/App/Controller/My.pm3
-rw-r--r--perllib/FixMyStreet/App/Controller/Photo.pm14
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm18
7 files changed, 208 insertions, 42 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index 133c83024..9c0018f38 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -9,6 +9,8 @@ use POSIX qw(strftime strcoll);
use Digest::SHA qw(sha1_hex);
use mySociety::EmailUtil qw(is_valid_email);
use if !$ENV{TRAVIS}, 'Image::Magick';
+use DateTime::Format::Strptime;
+
use FixMyStreet::SendReport;
@@ -130,9 +132,21 @@ sub index : Path : Args(0) {
$c->stash->{categories} = $c->cobrand->problems->categories_summary();
+ $c->stash->{total_bodies} = $c->model('DB::Body')->count();
+
return 1;
}
+sub config_page : Path( 'config' ) : Args(0) {
+ my ($self, $c) = @_;
+ my $dir = $c->stash->{additional_template_paths}->[0];
+ my $git_version = `cd $dir && git describe --tags`;
+ chomp $git_version;
+ $c->stash(
+ git_version => $git_version,
+ );
+}
+
sub timeline : Path( 'timeline' ) : Args(0) {
my ($self, $c) = @_;
@@ -411,7 +425,7 @@ sub update_contacts : Private {
sub body_params : Private {
my ( $self, $c ) = @_;
- my @fields = qw/name endpoint jurisdiction api_key send_method send_comments suppress_alerts send_extended_statuses comment_user_id can_be_devolved parent/;
+ my @fields = qw/name endpoint jurisdiction api_key send_method send_comments suppress_alerts send_extended_statuses comment_user_id can_be_devolved parent deleted/;
my %defaults = map { $_ => '' } @fields;
%defaults = ( %defaults,
send_comments => 0,
@@ -420,6 +434,7 @@ sub body_params : Private {
send_extended_statuses => 0,
can_be_devolved => 0,
parent => undef,
+ deleted => 0,
);
my %params = map { $_ => $c->req->param($_) || $defaults{$_} } @fields;
return \%params;
@@ -430,6 +445,7 @@ sub display_contacts : Private {
my $contacts = $c->stash->{body}->contacts->search(undef, { order_by => [ 'category' ] } );
$c->stash->{contacts} = $contacts;
+ $c->stash->{live_contacts} = $contacts->search({ deleted => 0 });
if ( $c->req->param('text') && $c->req->param('text') == 1 ) {
$c->stash->{template} = 'admin/council_contacts.txt';
@@ -546,10 +562,15 @@ sub reports : Path('reports') {
$query->{'-or'} = [
'me.areas' => { like => "%,$1,%" }
];
+ } elsif ($search =~ /^ref:(\d+)$/) {
+ $query->{'-or'} = [
+ 'me.external_id' => { like => "%$1%" }
+ ];
} else {
$query->{'-or'} = [
'me.id' => $search_n,
'user.email' => { ilike => $like_search },
+ 'me.external_id' => { ilike => $like_search },
'me.name' => { ilike => $like_search },
'me.title' => { ilike => $like_search },
detail => { ilike => $like_search },
@@ -749,11 +770,15 @@ sub report_edit : Path('report_edit') : Args(1) {
$problem->user( $user );
}
+ # Deal with photos
if ( $c->req->param('remove_photo') ) {
$problem->photo(undef);
}
+ if ( $new_state eq 'hidden' ) {
+ unlink glob FixMyStreet->path_to( 'web', 'photo', $problem->id . '.*' );
+ }
- if ( $new_state eq 'confirmed' and $old_state eq 'unconfirmed' ) {
+ if ( $problem->is_visible() and $old_state eq 'unconfirmed' ) {
$problem->confirmed( \'ms_current_timestamp()' );
}
@@ -894,7 +919,7 @@ sub update_edit : Path('update_edit') : Args(1) {
$update->name( $c->req->param('name') || '' );
$update->text( $c->req->param('text') );
$update->anonymous( $c->req->param('anonymous') );
- $update->state( $c->req->param('state') );
+ $update->state( $new_state );
if ( $c->req->param('email') ne $update->user->email ) {
my $user =
@@ -914,6 +939,10 @@ sub update_edit : Path('update_edit') : Args(1) {
}
}
+ if ( $new_state eq 'hidden' ) {
+ unlink glob FixMyStreet->path_to( 'web', 'photo', 'c', $update->id . '.*' );
+ }
+
$update->update;
$c->stash->{status_message} = '<p><em>' . _('Updated!') . '</em></p>';
@@ -954,6 +983,11 @@ sub user_add : Path('user_edit') : Args(0) {
$c->forward('check_token');
+ if ( $c->cobrand->moniker eq 'zurich' and $c->req->param('email') eq '' ) {
+ $c->stash->{field_errors}->{email} = _('Please enter a valid email');
+ return 1;
+ }
+
return unless $c->req->param('name') && $c->req->param('email');
my $user = $c->model('DB::User')->find_or_create( {
@@ -1001,6 +1035,11 @@ sub user_edit : Path('user_edit') : Args(1) {
$user->email( $c->req->param('email') );
$user->from_body( $c->req->param('body') || undef );
$user->flagged( $c->req->param('flagged') || 0 );
+
+ if ( $c->cobrand->moniker eq 'zurich' and $user->email eq '' ) {
+ $c->stash->{field_errors}->{email} = _('Please enter a valid email');
+ return 1;
+ }
$user->update;
if ($edited) {
@@ -1024,8 +1063,20 @@ sub flagged : Path('flagged') : Args(0) {
$c->stash->{problems} = [ $problems->all ];
my $users = $c->model('DB::User')->search( { flagged => 1 } );
+ my @users = $users->all;
+ my %email2user = map { $_->email => $_ } @users;
+ $c->stash->{users} = [ @users ];
- $c->stash->{users} = $users;
+ my @abuser_emails = $c->model('DB::Abuse')->all();
+
+ foreach my $email (@abuser_emails) {
+ # Slight abuse of the boolean flagged value
+ if ($email2user{$email->email}) {
+ $email2user{$email->email}->flagged( 2 );
+ } else {
+ push @{$c->stash->{users}}, { email => $email->email, flagged => 2 };
+ }
+ }
return 1;
}
@@ -1042,26 +1093,15 @@ sub stats : Path('stats') : Args(0) {
if ( $c->req->param('getcounts') ) {
my ( $start_date, $end_date, @errors );
+ my $parser = DateTime::Format::Strptime->new( pattern => '%d/%m/%Y' );
- eval {
- $start_date = DateTime->new(
- year => $c->req->param('start_date_year'),
- month => $c->req->param('start_date_month'),
- day => $c->req->param('start_date_day'),
- );
- };
+ $start_date = $parser-> parse_datetime ( $c->req->param('start_date') );
- push @errors, _('Invalid start date') if $@;
+ push @errors, _('Invalid start date') unless defined $start_date;
- eval {
- $end_date = DateTime->new(
- year => $c->req->param('end_date_year'),
- month => $c->req->param('end_date_month'),
- day => $c->req->param('end_date_day'),
- );
- };
+ $end_date = $parser-> parse_datetime ( $c->req->param('end_date') ) ;
- push @errors, _('Invalid end date') if $@;
+ push @errors, _('Invalid end date') unless defined $end_date;
$c->stash->{errors} = \@errors;
$c->stash->{start_date} = $start_date;
@@ -1148,6 +1188,7 @@ sub set_allowed_pages : Private {
'users' => [_('Users'), 5],
'flagged' => [_('Flagged'), 6],
'stats' => [_('Stats'), 6],
+ 'config' => [ undef, undef ],
'user_edit' => [undef, undef],
'body' => [undef, undef],
'body_edit' => [undef, undef],
diff --git a/perllib/FixMyStreet/App/Controller/Contact.pm b/perllib/FixMyStreet/App/Controller/Contact.pm
index 3fcb449d2..7ba18ed2d 100644
--- a/perllib/FixMyStreet/App/Controller/Contact.pm
+++ b/perllib/FixMyStreet/App/Controller/Contact.pm
@@ -149,7 +149,7 @@ sub prepare_params_for_email : Private {
my $problem_url = $base_url . '/report/' . $c->stash->{update}->problem_id
. '#update_' . $c->stash->{update}->id;
- my $admin_url = " - $admin_url" . 'update_edit/' . $c->stash->{update}->id
+ my $admin_url = " - $admin_url" . '/update_edit/' . $c->stash->{update}->id
if $admin_url;
$c->stash->{message} .= sprintf(
" \n\n[ Complaint about update %d on report %d - %s%s ]",
@@ -161,7 +161,7 @@ sub prepare_params_for_email : Private {
elsif ( $c->stash->{problem} ) {
my $problem_url = $base_url . '/report/' . $c->stash->{problem}->id;
- $admin_url = " - $admin_url" . 'report_edit/' . $c->stash->{problem}->id
+ $admin_url = " - $admin_url" . '/report_edit/' . $c->stash->{problem}->id
if $admin_url;
$c->stash->{message} .= sprintf(
" \n\n[ Complaint about report %d - %s%s ]",
diff --git a/perllib/FixMyStreet/App/Controller/Dashboard.pm b/perllib/FixMyStreet/App/Controller/Dashboard.pm
index 028b9aadd..b47a1f54b 100644
--- a/perllib/FixMyStreet/App/Controller/Dashboard.pm
+++ b/perllib/FixMyStreet/App/Controller/Dashboard.pm
@@ -121,16 +121,22 @@ sub index : Path : Args(0) {
if $c->stash->{category};
$c->stash->{where} = \%where;
my $prob_where = { %where };
- $prob_where->{state} = $prob_where->{'problem.state'};
+ $prob_where->{'me.state'} = $prob_where->{'problem.state'};
delete $prob_where->{'problem.state'};
$c->stash->{prob_where} = $prob_where;
+ my $dtf = $c->model('DB')->storage->datetime_parser;
+
my %counts;
my $t = DateTime->today;
- $counts{wtd} = $c->forward( 'updates_search', [ $t->subtract( days => $t->dow - 1 ) ] );
- $counts{week} = $c->forward( 'updates_search', [ DateTime->now->subtract( weeks => 1 ) ] );
- $counts{weeks} = $c->forward( 'updates_search', [ DateTime->now->subtract( weeks => 4 ) ] );
- $counts{ytd} = $c->forward( 'updates_search', [ DateTime->today->set( day => 1, month => 1 ) ] );
+ $counts{wtd} = $c->forward( 'updates_search',
+ [ $dtf->format_datetime( $t->subtract( days => $t->dow - 1 ) ) ] );
+ $counts{week} = $c->forward( 'updates_search',
+ [ $dtf->format_datetime( DateTime->now->subtract( weeks => 1 ) ) ] );
+ $counts{weeks} = $c->forward( 'updates_search',
+ [ $dtf->format_datetime( DateTime->now->subtract( weeks => 4 ) ) ] );
+ $counts{ytd} = $c->forward( 'updates_search',
+ [ $dtf->format_datetime( DateTime->today->set( day => 1, month => 1 ) ) ] );
$c->stash->{problems} = \%counts;
@@ -138,17 +144,19 @@ sub index : Path : Args(0) {
$c->stash->{q_state} = $c->req->param('state') || '';
if ( $c->stash->{q_state} eq 'fixed' ) {
- $prob_where->{state} = [ FixMyStreet::DB::Result::Problem->fixed_states() ];
+ $prob_where->{'me.state'} = [ FixMyStreet::DB::Result::Problem->fixed_states() ];
} elsif ( $c->stash->{q_state} ) {
- $prob_where->{state} = $c->stash->{q_state};
- $prob_where->{state} = { IN => [ 'planned', 'action scheduled' ] }
- if $prob_where->{state} eq 'action scheduled';
+ $prob_where->{'me.state'} = $c->stash->{q_state};
+ $prob_where->{'me.state'} = { IN => [ 'planned', 'action scheduled' ] }
+ if $prob_where->{'me.state'} eq 'action scheduled';
}
my $params = {
%$prob_where,
- 'me.confirmed' => { '>=', DateTime->now->subtract( days => 30 ) },
+ 'me.confirmed' => { '>=', $dtf->format_datetime( DateTime->now->subtract( days => 30 ) ) },
};
- my @problems = $c->cobrand->problems->search( $params )->all;
+ my $problems_rs = $c->cobrand->problems->search( $params );
+ my @problems = $problems_rs->all;
+
my %problems;
foreach (@problems) {
if ($_->confirmed >= DateTime->now->subtract(days => 7)) {
@@ -160,6 +168,102 @@ sub index : Path : Args(0) {
}
}
$c->stash->{lists} = \%problems;
+
+ if ( $c->req->params->{export} ) {
+ $self->export_as_csv($c, $problems_rs, $body);
+ }
+}
+
+sub export_as_csv {
+ my ($self, $c, $problems_rs, $body) = @_;
+ require Text::CSV;
+ my $problems = $problems_rs->search(
+ {}, { prefetch => 'comments' });
+
+ my $filename = do {
+ my %where = (
+ body => $body->id,
+ category => $c->stash->{category},
+ state => $c->stash->{q_state},
+ ward => $c->stash->{ward},
+ );
+ join '-',
+ $c->req->uri->host,
+ map {
+ my $value = $where{$_};
+ (defined $value and length $value) ? ($_, $value) : ()
+ } sort keys %where };
+
+ my $csv = Text::CSV->new();
+ $csv->combine(
+ 'Report ID',
+ 'Title',
+ 'Detail',
+ 'User Name',
+ 'Category',
+ 'Created',
+ 'Confirmed',
+ 'Acknowledged',
+ 'Fixed',
+ 'Closed',
+ 'Status',
+ 'Latitude', 'Longitude',
+ 'Nearest Postcode',
+ 'Report URL',
+ );
+ my @body = ($csv->string);
+
+ my $fixed_states = FixMyStreet::DB::Result::Problem->fixed_states;
+ my $closed_states = FixMyStreet::DB::Result::Problem->closed_states;
+
+ while ( my $report = $problems->next ) {
+ my $external_body;
+ my $body_name = "";
+ if ( $external_body = $report->body($c) ) {
+ # seems to be a zurich specific thing
+ $body_name = $external_body->name if ref $external_body;
+ }
+ my $hashref = $report->as_hashref($c);
+
+ $hashref->{user_name_display} = $report->anonymous?
+ '(anonymous)' : $report->user->name;
+
+ for my $comment ($report->comments) {
+ my $problem_state = $comment->problem_state or next;
+ next if $problem_state eq 'confirmed';
+ $hashref->{acknowledged_pp} //= $c->cobrand->prettify_dt( $comment->created );
+ $hashref->{fixed_pp} //= $fixed_states->{ $problem_state } ?
+ $c->cobrand->prettify_dt( $comment->created ): undef;
+ if ($closed_states->{ $problem_state }) {
+ $hashref->{closed_pp} = $c->cobrand->prettify_dt( $comment->created );
+ last;
+ }
+ }
+
+ $csv->combine(
+ @{$hashref}{
+ 'id',
+ 'title',
+ 'detail',
+ 'user_name_display',
+ 'category',
+ 'created_pp',
+ 'confirmed_pp',
+ 'acknowledged_pp',
+ 'fixed_pp',
+ 'closed_pp',
+ 'state',
+ 'latitude', 'longitude',
+ 'postcode',
+ },
+ (join '', $c->cobrand->base_url_for_report($report), $report->url),
+ );
+
+ push @body, $csv->string;
+ }
+ $c->res->content_type('text/csv; charset=utf-8');
+ $c->res->header('content-disposition' => "attachment; filename=${filename}.csv");
+ $c->res->body( join "\n", @body );
}
sub updates_search : Private {
diff --git a/perllib/FixMyStreet/App/Controller/FakeMapit.pm b/perllib/FixMyStreet/App/Controller/FakeMapit.pm
index bc46df712..253c75ba4 100755
--- a/perllib/FixMyStreet/App/Controller/FakeMapit.pm
+++ b/perllib/FixMyStreet/App/Controller/FakeMapit.pm
@@ -12,13 +12,13 @@ FixMyStreet::App::Controller::FakeMapit - Catalyst Controller
A controller to fake mapit when we don't have it. If you set MAPIT_URL to
.../fakemapit/ it should all just work, with a mapit that assumes the whole
-world is one area, with ID 161 and name "Default Area".
+world is one area, with ID 161 and name "Everywhere".
=head1 METHODS
=cut
-my $area = { "name" => "Default Area", "type" => "ZZZ", "id" => 161 };
+my $area = { "name" => "Everywhere", "type" => "ZZZ", "id" => 161 };
sub output : Private {
my ( $self, $c, $data ) = @_;
diff --git a/perllib/FixMyStreet/App/Controller/My.pm b/perllib/FixMyStreet/App/Controller/My.pm
index c00264315..bbef1f8d8 100644
--- a/perllib/FixMyStreet/App/Controller/My.pm
+++ b/perllib/FixMyStreet/App/Controller/My.pm
@@ -45,6 +45,7 @@ sub my : Path : Args(0) {
} )->page( $p_page );
while ( my $problem = $rs->next ) {
+ $c->stash->{has_content}++;
push @$pins, {
latitude => $problem->latitude,
longitude => $problem->longitude,
@@ -64,7 +65,9 @@ sub my : Path : Args(0) {
order_by => { -desc => 'confirmed' },
rows => 50
} )->page( $u_page );
+
my @updates = $rs->all;
+ $c->stash->{has_content} += scalar @updates;
$c->stash->{updates} = \@updates;
$c->stash->{updates_pager} = $rs->pager;
diff --git a/perllib/FixMyStreet/App/Controller/Photo.pm b/perllib/FixMyStreet/App/Controller/Photo.pm
index 8b00d1533..09afabecf 100644
--- a/perllib/FixMyStreet/App/Controller/Photo.pm
+++ b/perllib/FixMyStreet/App/Controller/Photo.pm
@@ -30,17 +30,19 @@ Display a photo
=cut
-sub during :LocalRegex('^([0-9a-f]{40})\.temp\.jpeg$') {
+sub during :LocalRegex('^([0-9a-f]{40})\.(temp|fulltemp)\.jpeg$') {
my ( $self, $c ) = @_;
- my ( $hash ) = @{ $c->req->captures };
+ my ( $hash, $size ) = @{ $c->req->captures };
my $file = file( $c->config->{UPLOAD_DIR}, "$hash.jpeg" );
my $photo = $file->slurp;
- if ( $c->cobrand->default_photo_resize ) {
- $photo = _shrink( $photo, $c->cobrand->default_photo_resize );
- } else {
- $photo = _shrink( $photo, '250x250' );
+ if ( $size eq 'temp' ) {
+ if ( $c->cobrand->default_photo_resize ) {
+ $photo = _shrink( $photo, $c->cobrand->default_photo_resize );
+ } else {
+ $photo = _shrink( $photo, '250x250' );
+ }
}
$c->forward( 'output', [ $photo ] );
diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm
index 128ef2790..a419e9cc1 100644
--- a/perllib/FixMyStreet/App/Controller/Report/New.pm
+++ b/perllib/FixMyStreet/App/Controller/Report/New.pm
@@ -585,7 +585,7 @@ sub setup_categories_and_bodies : Private {
my $first_area = ( values %$all_areas )[0];
my @bodies = $c->model('DB::Body')->search(
- { 'body_areas.area_id' => [ keys %$all_areas ] },
+ { 'body_areas.area_id' => [ keys %$all_areas ], deleted => 0 },
{ join => 'body_areas' }
)->all;
my %bodies = map { $_->id => $_ } @bodies;
@@ -666,6 +666,15 @@ sub setup_categories_and_bodies : Private {
}
}
+ if ($c->cobrand->can('hidden_categories')) {
+ my %hidden_categories = map { $_ => 1 }
+ $c->cobrand->hidden_categories;
+
+ @category_options = grep {
+ !$hidden_categories{$_}
+ } @category_options;
+ }
+
# put results onto stash for display
$c->stash->{bodies} = \%bodies;
$c->stash->{all_body_names} = [ map { $_->name } values %bodies ];
@@ -957,6 +966,13 @@ sub check_for_errors : Private {
delete $field_errors{name};
my $report = $c->stash->{report};
$report->title( Utils::cleanup_text( substr($report->detail, 0, 25) ) );
+
+ # We only want to validate the phone number web requests (where the
+ # service parameter is blank) because previous versions of the mobile
+ # apps don't validate the presence of a phone number.
+ if ( ! $c->req->param('phone') and ! $c->req->param('service') ) {
+ $field_errors{phone} = _("This information is required");
+ }
}
# FIXME: need to check for required bromley fields here