diff options
Diffstat (limited to 'perllib/FixMyStreet/App/Controller')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 81 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Contact.pm | 4 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Dashboard.pm | 126 | ||||
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/FakeMapit.pm | 4 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/My.pm | 3 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Photo.pm | 14 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 18 |
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 |