diff options
Diffstat (limited to 'perllib/FixMyStreet/App/Controller')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 222 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Around.pm | 7 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Auth.pm | 13 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Contact.pm | 15 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Dashboard.pm | 16 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Moderate.pm | 4 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/My.pm | 14 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Photo.pm | 163 | ||||
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Questionnaire.pm | 14 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report.pm | 19 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 45 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/Update.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Reports.pm | 46 | ||||
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Rss.pm | 6 | ||||
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Status.pm | 70 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Tokens.pm | 8 |
16 files changed, 412 insertions, 252 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 6145a6eb0..a61032988 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -10,6 +10,7 @@ use Digest::SHA qw(sha1_hex); use mySociety::EmailUtil qw(is_valid_email); use if !$ENV{TRAVIS}, 'Image::Magick'; use DateTime::Format::Strptime; +use List::Util 'first'; use FixMyStreet::SendReport; @@ -70,8 +71,6 @@ sub index : Path : Args(0) { return $c->cobrand->admin(); } - my $site_restriction = $c->cobrand->site_restriction(); - my $problems = $c->cobrand->problems->summary_count; my %prob_counts = @@ -85,7 +84,7 @@ sub index : Path : Args(0) { for ( FixMyStreet::DB::Result::Problem->visible_states() ); $c->stash->{total_problems_users} = $c->cobrand->problems->unique_users; - my $comments = $c->model('DB::Comment')->summary_count( $site_restriction ); + my $comments = $c->model('DB::Comment')->summary_count( $c->cobrand->body_restriction ); my %comment_counts = map { $_->state => $_->get_column('state_count') } $comments->all; @@ -130,7 +129,9 @@ sub index : Path : Args(0) { : _('n/a'); $c->stash->{questionnaires} = \%questionnaire_counts; - $c->stash->{categories} = $c->cobrand->problems->categories_summary(); + if ($c->get_param('show_categories')) { + $c->stash->{categories} = $c->cobrand->problems->categories_summary(); + } $c->stash->{total_bodies} = $c->model('DB::Body')->count(); @@ -150,7 +151,6 @@ sub config_page : Path( 'config' ) : Args(0) { sub timeline : Path( 'timeline' ) : Args(0) { my ($self, $c) = @_; - my $site_restriction = $c->cobrand->site_restriction(); my %time; $c->model('DB')->schema->storage->sql_maker->quote_char( '"' ); @@ -171,7 +171,7 @@ sub timeline : Path( 'timeline' ) : Args(0) { push @{$time{$_->whenanswered->epoch}}, { type => 'quesAnswered', date => $_->whenanswered, obj => $_ } if $_->whenanswered; } - my $updates = $c->model('DB::Comment')->timeline( $site_restriction ); + my $updates = $c->model('DB::Comment')->timeline( $c->cobrand->body_restriction ); foreach ($updates->all) { push @{$time{$_->created->epoch}}, { type => 'update', date => $_->created, obj => $_} ; @@ -359,13 +359,21 @@ sub update_contacts : Private { $contact->deleted( $c->get_param('deleted') ? 1 : 0 ); $contact->non_public( $c->get_param('non_public') ? 1 : 0 ); $contact->note( $c->get_param('note') ); - $contact->whenedited( \'ms_current_timestamp()' ); + $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 the photo_required flag in extra to the appropriate value + if ( $c->get_param('photo_required') ) { + $contact->set_extra_metadata_if_undefined( photo_required => 1 ); + } + else { + $contact->unset_extra_metadata( 'photo_required' ); + } + if ( %errors ) { $c->stash->{updated} = _('Please correct the errors below'); $c->stash->{contact} = $contact; @@ -395,7 +403,7 @@ sub update_contacts : Private { $contacts->update( { confirmed => 1, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'Confirmed', editor => $editor, } @@ -538,8 +546,6 @@ sub reports : Path('reports') { if (my $search = $c->get_param('search')) { $c->stash->{searched} = $search; - my $site_restriction = $c->cobrand->site_restriction; - my $search_n = 0; $search_n = int($search) if $search =~ /^\d+$/; @@ -616,9 +622,10 @@ sub reports : Path('reports') { } if (@$query) { - my $updates = $c->model('DB::Comment')->search( + my $updates = $c->model('DB::Comment') + ->to_body($c->cobrand->body_restriction) + ->search( { - %{ $site_restriction }, -or => $query, }, { @@ -650,8 +657,6 @@ sub reports : Path('reports') { sub report_edit : Path('report_edit') : Args(1) { my ( $self, $c, $id ) = @_; - my $site_restriction = $c->cobrand->site_restriction; - my $problem = $c->cobrand->problems->search( { id => $id } )->first; $c->detach( '/page_error_404_not_found' ) @@ -675,12 +680,21 @@ sub report_edit : Path('report_edit') : Args(1) { type => 'big', } ] : [], + print_report => 1, ); } - if ( $c->get_param('rotate_photo') ) { - $c->forward('rotate_photo'); - return 1; + if (my $rotate_photo_param = $self->_get_rotate_photo_param($c)) { + $self->rotate_photo($c, @$rotate_photo_param); + if ( $c->cobrand->moniker eq 'zurich' ) { + # Clicking the photo rotation buttons should do nothing + # except for rotating the photo, so return the user + # to the report screen now. + $c->res->redirect( $c->uri_for( 'report_edit', $problem->id ) ); + return; + } else { + return 1; + } } if ( $c->cobrand->moniker eq 'zurich' ) { @@ -707,7 +721,7 @@ sub report_edit : Path('report_edit') : Args(1) { } elsif ( $c->get_param('mark_sent') ) { $c->forward('check_token'); - $problem->whensent(\'ms_current_timestamp()'); + $problem->whensent(\'current_timestamp'); $problem->update(); $c->stash->{status_message} = '<p><em>' . _('That problem has been marked as sent.') . '</em></p>'; $c->forward( 'log_edit', [ $id, 'problem', 'marked sent' ] ); @@ -787,14 +801,14 @@ sub report_edit : Path('report_edit') : Args(1) { } if ( $problem->is_visible() and $old_state eq 'unconfirmed' ) { - $problem->confirmed( \'ms_current_timestamp()' ); + $problem->confirmed( \'current_timestamp' ); } if ($done) { $problem->discard_changes; } else { - $problem->lastupdate( \'ms_current_timestamp()' ) if $edited || $new_state ne $old_state; + $problem->lastupdate( \'current_timestamp' ) if $edited || $new_state ne $old_state; $problem->update; if ( $new_state ne $old_state ) { @@ -816,6 +830,85 @@ sub report_edit : Path('report_edit') : Args(1) { return 1; } +sub templates : Path('templates') : Args(0) { + my ( $self, $c ) = @_; + + $c->detach( '/page_error_404_not_found' ) + unless $c->cobrand->moniker eq 'zurich'; + + my $user = $c->user; + + $self->templates_for_body($c, $user->from_body ); +} + +sub templates_view : Path('templates') : Args(1) { + my ($self, $c, $body_id) = @_; + + $c->detach( '/page_error_404_not_found' ) + unless $c->cobrand->moniker eq 'zurich'; + + # e.g. for admin + + my $body = $c->model('DB::Body')->find($body_id) + or $c->detach( '/page_error_404_not_found' ); + + $self->templates_for_body($c, $body); +} + +sub template_edit : Path('templates') : Args(2) { + my ( $self, $c, $body_id, $template_id ) = @_; + + $c->detach( '/page_error_404_not_found' ) + unless $c->cobrand->moniker eq 'zurich'; + + my $body = $c->model('DB::Body')->find($body_id) + or $c->detach( '/page_error_404_not_found' ); + $c->stash->{body} = $body; + + my $template; + if ($template_id eq 'new') { + $template = $body->response_templates->new({}); + } + else { + $template = $body->response_templates->find( $template_id ) + or $c->detach( '/page_error_404_not_found' ); + } + + if ($c->req->method eq 'POST') { + if ($c->get_param('delete_template') eq _("Delete template")) { + $template->delete; + } else { + $template->title( $c->get_param('title') ); + $template->text ( $c->get_param('text') ); + $template->update_or_insert; + } + + $c->res->redirect( $c->uri_for( 'templates', $body->id ) ); + } + + $c->stash->{response_template} = $template; + + $c->stash->{template} = 'admin/template_edit.html'; +} + + +sub templates_for_body { + my ( $self, $c, $body ) = @_; + + $c->stash->{body} = $body; + + my @templates = $body->response_templates->search( + undef, + { + order_by => 'title' + } + ); + + $c->stash->{response_templates} = \@templates; + + $c->stash->{template} = 'admin/templates.html'; +} + sub users: Path('users') : Args(0) { my ( $self, $c ) = @_; @@ -874,13 +967,9 @@ sub users: Path('users') : Args(0) { sub update_edit : Path('update_edit') : Args(1) { my ( $self, $c, $id ) = @_; - my $site_restriction = $c->cobrand->site_restriction; - my $update = $c->model('DB::Comment')->search( - { - id => $id, - %{$site_restriction}, - } - )->first; + my $update = $c->model('DB::Comment') + ->to_body($c->cobrand->body_restriction) + ->search({ id => $id })->first; $c->detach( '/page_error_404_not_found' ) unless $update; @@ -943,10 +1032,10 @@ sub update_edit : Path('update_edit') : Args(1) { } if ( $new_state eq 'confirmed' and $old_state eq 'unconfirmed' ) { - $update->confirmed( \'ms_current_timestamp()' ); + $update->confirmed( \'current_timestamp' ); if ( $update->problem_state && $update->created > $update->problem->lastupdate ) { $update->problem->state( $update->problem_state ); - $update->problem->lastupdate( \'ms_current_timestamp()' ); + $update->problem->lastupdate( \'current_timestamp' ); $update->problem->update; } } @@ -1064,7 +1153,7 @@ sub user_edit : Path('user_edit') : Args(1) { sub flagged : Path('flagged') : Args(0) { my ( $self, $c ) = @_; - my $problems = $c->model('DB::Problem')->search( { flagged => 1 } ); + my $problems = $c->cobrand->problems->search( { flagged => 1 } ); # pass in as array ref as using same template as search_reports # which has to use an array ref for sql quoting reasons @@ -1121,9 +1210,6 @@ sub stats : Path('stats') : Args(0) { my $bymonth = $c->get_param('bymonth'); $c->stash->{bymonth} = $bymonth; - my ( %body, %dates ); - $body{bodies_str} = { like => $c->get_param('body') } - if $c->get_param('body'); $c->stash->{selected_body} = $c->get_param('body'); @@ -1154,14 +1240,12 @@ sub stats : Path('stats') : Args(0) { ); } - my $p = $c->model('DB::Problem')->search( + my $p = $c->cobrand->problems->to_body($c->get_param('body'))->search( { -AND => [ $field => { '>=', $start_date}, $field => { '<=', $end_date + $one_day }, ], - %body, - %dates, }, \%select, ); @@ -1266,13 +1350,24 @@ Adds an entry into the admin_log table using the current user. =cut sub log_edit : Private { - my ( $self, $c, $id, $object_type, $action ) = @_; + my ( $self, $c, $id, $object_type, $action, $time_spent ) = @_; + + $time_spent //= 0; + $time_spent = 0 if $time_spent < 0; + + my $user_object = do { + my $auth_user = $c->user; + $auth_user ? $auth_user->get_object : undef; + }; + $c->model('DB::AdminLog')->create( { admin_user => $c->forward('get_user'), + $user_object ? ( user => $user_object ) : (), # as (rel => undef) doesn't work object_type => $object_type, action => $action, object_id => $id, + time_spent => $time_spent, } )->insert(); } @@ -1385,36 +1480,27 @@ Rotate a photo 90 degrees left or right =cut +# returns index of photo to rotate, if any +sub _get_rotate_photo_param { + my ($self, $c) = @_; + my $key = first { /^rotate_photo/ } keys %{ $c->req->params } or return; + my ($index) = $key =~ /(\d+)$/; + my $direction = $c->get_param($key); + return [ $index || 0, $key, $direction ]; +} + sub rotate_photo : Private { - my ( $self, $c ) =@_; + my ( $self, $c, $index, $key, $direction ) = @_; - my $direction = $c->get_param('rotate_photo'); return unless $direction eq _('Rotate Left') or $direction eq _('Rotate Right'); - my $photo = $c->stash->{problem}->photo; - my $file; + my $problem = $c->stash->{problem}; + my $fileid = $problem->get_photoset($c)->rotate_image( + $index, + $direction eq _('Rotate Left') ? -90 : 90 + ) or return; - # If photo field contains a hash - if ( length($photo) == 40 ) { - $file = file( $c->config->{UPLOAD_DIR}, "$photo.jpeg" ); - $photo = $file->slurp; - } - - $photo = _rotate_image( $photo, $direction eq _('Rotate Left') ? -90 : 90 ); - return unless $photo; - - # Write out to new location - my $fileid = sha1_hex($photo); - $file = file( $c->config->{UPLOAD_DIR}, "$fileid.jpeg" ); - - my $fh = $file->open('w'); - print $fh $photo; - close $fh; - - unlink glob FixMyStreet->path_to( 'web', 'photo', $c->stash->{problem}->id . '.*' ); - - $c->stash->{problem}->photo( $fileid ); - $c->stash->{problem}->update(); + $problem->update({ photo => $fileid }); return 1; } @@ -1464,18 +1550,6 @@ sub trim { return $e; } -sub _rotate_image { - my ($photo, $direction) = @_; - my $image = Image::Magick->new; - $image->BlobToImage($photo); - my $err = $image->Rotate($direction); - return 0 if $err; - my @blobs = $image->ImageToBlob(); - undef $image; - return $blobs[0]; -} - - =head1 AUTHOR Struan Donald diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm index 723684793..4aa695ae5 100644 --- a/perllib/FixMyStreet/App/Controller/Around.pm +++ b/perllib/FixMyStreet/App/Controller/Around.pm @@ -28,7 +28,7 @@ If no search redirect back to the homepage. =cut -sub around_index : Path : Args(0) { +sub index : Path : Args(0) { my ( $self, $c ) = @_; # handle old coord systems @@ -302,15 +302,10 @@ sub ajax : Path('/ajax') { 'around/on_map_list_items.html', { on_map => $on_map, around_map => $around_map } ); - my $around_map_list_html = $c->render_fragment( - 'around/around_map_list_items.html', - { on_map => $on_map, around_map => $around_map } - ); # JSON encode the response my $json = { pins => $pins }; $json->{current} = $on_map_list_html if $on_map_list_html; - $json->{current_near} = $around_map_list_html if $around_map_list_html; my $body = JSON->new->utf8(1)->encode($json); $c->res->body($body); } diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm index 63bf91ff5..6de416c53 100644 --- a/perllib/FixMyStreet/App/Controller/Auth.pm +++ b/perllib/FixMyStreet/App/Controller/Auth.pm @@ -36,16 +36,23 @@ sub general : Path : Args(0) { return unless $c->req->method eq 'POST'; # decide which action to take - my $has_password = $c->get_param('sign_in') || $c->get_param('password_sign_in'); - my $has_email = $c->get_param('email_sign_in') || $c->get_param('name') || $c->get_param('password_register'); + my $clicked_password = $c->get_param('sign_in'); + my $clicked_email = $c->get_param('email_sign_in'); + my $data_password = $c->get_param('password_sign_in'); + my $data_email = $c->get_param('name') || $c->get_param('password_register'); - $c->detach('email_sign_in') if $has_email && !$has_password; + $c->detach('email_sign_in') if $clicked_email || ($data_email && !$data_password); $c->forward( 'sign_in' ) && $c->detach( 'redirect_on_signin', [ $c->get_param('r') ] ); } +sub general_test : Path('_test_') : Args(0) { + my ( $self, $c ) = @_; + $c->stash->{template} = 'auth/token.html'; +} + =head2 sign_in Allow the user to sign in with a username and a password. diff --git a/perllib/FixMyStreet/App/Controller/Contact.pm b/perllib/FixMyStreet/App/Controller/Contact.pm index 912224649..115f4e3d2 100644 --- a/perllib/FixMyStreet/App/Controller/Contact.pm +++ b/perllib/FixMyStreet/App/Controller/Contact.pm @@ -5,6 +5,7 @@ use namespace::autoclean; BEGIN { extends 'Catalyst::Controller'; } use mySociety::EmailUtil; +use FixMyStreet::Email; =head1 NAME @@ -239,11 +240,19 @@ sub send_email : Private { ? ' ( forwarded from ' . $c->req->header('X-Forwarded-For') . ' )' : ''; - $c->send_email( 'contact.txt', { + my $from = [ $c->stash->{em}, $c->stash->{form_name} ]; + my $params = { to => [ [ $recipient, _($recipient_name) ] ], - from => [ $c->stash->{em}, $c->stash->{form_name} ], subject => 'FMS message: ' . $c->stash->{subject}, - }); + }; + if (FixMyStreet::Email::test_dmarc($c->stash->{em})) { + $params->{'Reply-To'} = [ $from ]; + $params->{from} = [ $recipient, $c->stash->{form_name} ]; + } else { + $params->{from} = $from; + } + + $c->send_email('contact.txt', $params); # above is always succesful :( $c->stash->{success} = 1; diff --git a/perllib/FixMyStreet/App/Controller/Dashboard.pm b/perllib/FixMyStreet/App/Controller/Dashboard.pm index c3aa35008..faddaa89e 100644 --- a/perllib/FixMyStreet/App/Controller/Dashboard.pm +++ b/perllib/FixMyStreet/App/Controller/Dashboard.pm @@ -89,6 +89,7 @@ sub index : Path : Args(0) { my ( $self, $c ) = @_; my $body = $c->forward('check_page_allowed'); + $c->stash->{body} = $body; # Set up the data for the dropdowns @@ -112,7 +113,6 @@ sub index : Path : Args(0) { $c->stash->{category} = $c->get_param('category'); my %where = ( - bodies_str => $body->id, # XXX Does this break in a two tier council? Restriction needs looking at... 'problem.state' => [ FixMyStreet::DB::Result::Problem->visible_states() ], ); $where{areas} = { 'like', '%,' . $c->stash->{ward} . ',%' } @@ -155,7 +155,7 @@ sub index : Path : Args(0) { %$prob_where, 'me.confirmed' => { '>=', $dtf->format_datetime( $now->clone->subtract( days => 30 ) ) }, }; - my $problems_rs = $c->cobrand->problems->search( $params ); + my $problems_rs = $c->cobrand->problems->to_body($body)->search( $params ); my @problems = $problems_rs->all; my %problems; @@ -270,12 +270,14 @@ sub export_as_csv { sub updates_search : Private { my ( $self, $c, $time ) = @_; + my $body = $c->stash->{body}; + my $params = { %{$c->stash->{where}}, 'me.confirmed' => { '>=', $time }, }; - my $comments = $c->model('DB::Comment')->search( + my $comments = $c->model('DB::Comment')->to_body($body)->search( $params, { group_by => [ 'problem_state' ], @@ -302,7 +304,7 @@ sub updates_search : Private { my $col = shift @$vars; my $substmt = "select min(id) from comment where me.problem_id=comment.problem_id and problem_state in ('" . join("','", @$vars) . "')"; - $comments = $c->model('DB::Comment')->search( + $comments = $c->model('DB::Comment')->to_body($body)->search( { %$params, problem_state => $vars, 'me.id' => \"= ($substmt)", @@ -319,7 +321,7 @@ sub updates_search : Private { $counts{$col} = int( ($comments->get_column('time')||0) / 60 / 60 / 24 + 0.5 ); } - $counts{fixed_user} = $c->model('DB::Comment')->search( + $counts{fixed_user} = $c->model('DB::Comment')->to_body($body)->search( { %$params, mark_fixed => 1, problem_state => undef }, { join => 'problem' } )->count; @@ -327,7 +329,7 @@ sub updates_search : Private { %{$c->stash->{prob_where}}, 'me.confirmed' => { '>=', $time }, }; - $counts{total} = $c->cobrand->problems->search( $params )->count; + $counts{total} = $c->cobrand->problems->to_body($body)->search( $params )->count; $params = { %{$c->stash->{prob_where}}, @@ -335,7 +337,7 @@ sub updates_search : Private { state => 'confirmed', '(select min(id) from comment where me.id=problem_id and problem_state is not null)' => undef, }; - $counts{not_marked} = $c->cobrand->problems->search( $params )->count; + $counts{not_marked} = $c->cobrand->problems->to_body($body)->search( $params )->count; return \%counts; } diff --git a/perllib/FixMyStreet/App/Controller/Moderate.pm b/perllib/FixMyStreet/App/Controller/Moderate.pm index 08c4280a1..77a3346dc 100644 --- a/perllib/FixMyStreet/App/Controller/Moderate.pm +++ b/perllib/FixMyStreet/App/Controller/Moderate.pm @@ -102,9 +102,6 @@ sub report_moderate_audit : Private { my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($problem->cobrand)->new(); - my $sender = FixMyStreet->config('DO_NOT_REPLY_EMAIL'); - my $sender_name = _($cobrand->contact_name); - my $token = $c->model("DB::Token")->create({ scope => 'moderation', data => { id => $problem->id } @@ -113,7 +110,6 @@ sub report_moderate_audit : Private { $c->send_email( 'problem-moderated.txt', { to => [ [ $user->email, $user->name ] ], - from => [ $sender, $sender_name ], types => $types_csv, user => $user, problem => $problem, diff --git a/perllib/FixMyStreet/App/Controller/My.pm b/perllib/FixMyStreet/App/Controller/My.pm index 83d5f7adb..3c4ce2cf7 100644 --- a/perllib/FixMyStreet/App/Controller/My.pm +++ b/perllib/FixMyStreet/App/Controller/My.pm @@ -31,16 +31,12 @@ sub my : Path : Args(0) { $c->forward( '/reports/stash_report_filter_status' ); my $pins = []; - my $problems = {}; + my $problems = []; my $states = $c->stash->{filter_problem_states}; my $params = { state => [ keys %$states ], }; - $params = { - %{ $c->cobrand->problems_clause }, - %$params - } if $c->cobrand->problems_clause; my $category = $c->get_param('filter_category'); if ( $category ) { @@ -48,7 +44,9 @@ sub my : Path : Args(0) { $c->stash->{filter_category} = $category; } - my $rs = $c->user->problems->search( $params, { + my $rs = $c->user->problems + ->to_body($c->cobrand->body_restriction) + ->search( $params, { order_by => { -desc => 'confirmed' }, rows => 50 } )->page( $p_page ); @@ -62,9 +60,7 @@ sub my : Path : Args(0) { id => $problem->id, title => $problem->title, }; - my $state = $problem->is_fixed ? 'fixed' : $problem->is_closed ? 'closed' : 'confirmed'; - push @{ $problems->{$state} }, $problem; - push @{ $problems->{all} }, $problem; + push @$problems, $problem; } $c->stash->{problems_pager} = $rs->pager; $c->stash->{problems} = $problems; diff --git a/perllib/FixMyStreet/App/Controller/Photo.pm b/perllib/FixMyStreet/App/Controller/Photo.pm index a2ec7d4c8..bc72f4bfb 100644 --- a/perllib/FixMyStreet/App/Controller/Photo.pm +++ b/perllib/FixMyStreet/App/Controller/Photo.pm @@ -8,8 +8,8 @@ use DateTime::Format::HTTP; use Digest::SHA qw(sha1_hex); use File::Path; use File::Slurp; -use Image::Size; use Path::Class; +use FixMyStreet::App::Model::PhotoSet; use if !$ENV{TRAVIS}, 'Image::Magick'; =head1 NAME @@ -49,13 +49,13 @@ sub during :LocalRegex('^([0-9a-f]{40})\.(temp|fulltemp)\.jpeg$') { $c->forward( 'output', [ $photo ] ); } -sub index :LocalRegex('^(c/)?(\d+)(?:\.(full|tn|fp))?\.jpeg$') { +sub index :LocalRegex('^(c/)?(\d+)(?:\.(\d+))?(?:\.(full|tn|fp))?\.jpeg$') { my ( $self, $c ) = @_; - my ( $is_update, $id, $size ) = @{ $c->req->captures }; + my ( $is_update, $id, $photo_number, $size ) = @{ $c->req->captures }; - my @photo; + my $item; if ( $is_update ) { - @photo = $c->model('DB::Comment')->search( { + ($item) = $c->model('DB::Comment')->search( { id => $id, state => 'confirmed', photo => { '!=', undef }, @@ -67,34 +67,40 @@ sub index :LocalRegex('^(c/)?(\d+)(?:\.(full|tn|fp))?\.jpeg$') { } $c->detach( 'no_photo' ) if $id =~ /\D/; - @photo = $c->cobrand->problems->search( { + ($item) = $c->cobrand->problems->search( { id => $id, state => [ FixMyStreet::DB::Result::Problem->visible_states(), 'partial' ], photo => { '!=', undef }, } ); } - $c->detach( 'no_photo' ) unless @photo; + $c->detach( 'no_photo' ) unless $item; - my $item = $photo[0]; $c->detach( 'no_photo' ) unless $c->cobrand->allow_photo_display($item); # Should only be for reports, not updates - my $photo = $item->photo; - # If photo field contains a hash - if (length($photo) == 40) { - my $file = file( $c->config->{UPLOAD_DIR}, "$photo.jpeg" ); - $photo = $file->slurp; - } - - if ( $size eq 'tn' ) { - $photo = _shrink( $photo, 'x100' ); - } elsif ( $size eq 'fp' ) { - $photo = _crop( $photo ); - } elsif ( $size eq 'full' ) { - } elsif ( $c->cobrand->default_photo_resize ) { - $photo = _shrink( $photo, $c->cobrand->default_photo_resize ); + my $photo; + if ($item->can('get_photoset')) { + $photo = $item->get_photoset( $c ) + ->get_image_data( num => $photo_number, size => $size ) + or $c->detach( 'no_photo' ); } else { - $photo = _shrink( $photo, '250x250' ); + $photo = $item->photo; + # If photo field contains a hash + if (length($photo) == 40) { + my $file = file( $c->config->{UPLOAD_DIR}, "$photo.jpeg" ); + $photo = $file->slurp; + } + + if ( $size eq 'tn' ) { + $photo = _shrink( $photo, 'x100' ); + } elsif ( $size eq 'fp' ) { + $photo = _crop( $photo ); + } elsif ( $size eq 'full' ) { + } elsif ( $c->cobrand->default_photo_resize ) { + $photo = _shrink( $photo, $c->cobrand->default_photo_resize ); + } else { + $photo = _shrink( $photo, '250x250' ); + } } $c->forward( 'output', [ $photo ] ); @@ -156,84 +162,67 @@ sub process_photo : Private { my ( $self, $c ) = @_; return - $c->forward('process_photo_upload') - || $c->forward('process_photo_cache') + $c->forward('process_photo_upload_or_cache') + || $c->forward('process_photo_required') || 1; # always return true } -sub process_photo_upload : Private { +sub process_photo_upload_or_cache : Private { my ( $self, $c ) = @_; - - # check for upload or return - my $upload = $c->req->upload('photo') - || return; - - # check that the photo is a jpeg - my $ct = $upload->type; - $ct =~ s/x-citrix-//; # Thanks, Citrix - # Had a report of a JPEG from an Android 2.1 coming through as a byte stream - unless ( $ct eq 'image/jpeg' || $ct eq 'image/pjpeg' || $ct eq 'application/octet-stream' ) { - $c->log->info('Bad photo tried to upload, type=' . $ct); - $c->stash->{photo_error} = _('Please upload a JPEG image only'); - return; - } - - # get the photo into a variable - my $photo_blob = eval { - my $filename = $upload->tempname; - my $out = `jhead -se -autorot $filename 2>&1`; - unless (defined $out) { - my ($w, $h, $err) = Image::Size::imgsize($filename); - die _("Please upload a JPEG image only") . "\n" if !defined $w || $err ne 'JPG'; - } - die _("Please upload a JPEG image only") . "\n" if $out && $out =~ /Not JPEG:/; - my $photo = $upload->slurp; - return $photo; - }; - if ( my $error = $@ ) { - my $format = _( -"That image doesn't appear to have uploaded correctly (%s), please try again." - ); - $c->stash->{photo_error} = sprintf( $format, $error ); - return; - } - - # we have an image we can use - save it to the upload dir for storage - my $cache_dir = dir( $c->config->{UPLOAD_DIR} ); - $cache_dir->mkpath; - unless ( -d $cache_dir && -w $cache_dir ) { - warn "Can't find/write to photo cache directory '$cache_dir'"; - return; - } - - my $fileid = sha1_hex($photo_blob); - $upload->copy_to( file($cache_dir, $fileid . '.jpeg') ); - - # stick the hash on the stash, so don't have to reupload in case of error - $c->stash->{upload_fileid} = $fileid; - + my @items = ( + ( map { + /^photo/ ? # photo, photo1, photo2 etc. + ($c->req->upload($_)) : () + } sort $c->req->upload), + split /,/, ($c->get_param('upload_fileid') || '') + ); + + my $photoset = FixMyStreet::App::Model::PhotoSet->new({ + c => $c, + data_items => \@items, + }); + + my $fileid = $photoset->data; + + $c->stash->{upload_fileid} = $fileid or return; return 1; } -=head2 process_photo_cache +=head2 process_photo_required + +Checks that a report has a photo attached if any of its Contacts +require it (by setting extra->photo_required == 1). Puts an error in +photo_error on the stash if it's required and missing, otherwise returns +true. -Look for the upload_fileid parameter and check it matches a file on disk. If it -does return true and put fileid on stash, otherwise false. +(Note that as we have reached this action, we *know* that the photo +is missing, otherwise it would have already been handled.) =cut -sub process_photo_cache : Private { +sub process_photo_required : Private { my ( $self, $c ) = @_; - # get the fileid and make sure it is just a hex number - my $fileid = $c->get_param('upload_fileid') || ''; - $fileid =~ s{[^0-9a-f]}{}gi; - return unless $fileid; - - my $file = file( $c->config->{UPLOAD_DIR}, "$fileid.jpeg" ); - return unless -e $file; + # load the report + my $report = $c->stash->{report} or return 1; # don't check photo for updates + my $bodies = $c->stash->{bodies}; + + my @contacts = $c-> # + model('DB::Contact') # + ->not_deleted # + ->search( + { + body_id => [ keys %$bodies ], + category => $report->category + } + )->all; + foreach my $contact ( @contacts ) { + if ( $contact->get_extra_metadata('photo_required') ) { + $c->stash->{photo_error} = _("Photo is required."); + return; + } + } - $c->stash->{upload_fileid} = $fileid; return 1; } diff --git a/perllib/FixMyStreet/App/Controller/Questionnaire.pm b/perllib/FixMyStreet/App/Controller/Questionnaire.pm index f9a08e408..8fe2514c0 100755 --- a/perllib/FixMyStreet/App/Controller/Questionnaire.pm +++ b/perllib/FixMyStreet/App/Controller/Questionnaire.pm @@ -142,8 +142,8 @@ sub submit_creator_fixed : Private { $questionnaire->ever_reported( $c->stash->{reported} eq 'Yes' ? 1 : 0 ); $questionnaire->old_state( $old_state ); - $questionnaire->whensent( \'ms_current_timestamp()' ); - $questionnaire->whenanswered( \'ms_current_timestamp()' ); + $questionnaire->whensent( \'current_timestamp' ); + $questionnaire->whenanswered( \'current_timestamp' ); $questionnaire->insert; } @@ -173,13 +173,13 @@ sub submit_standard : Private { # Record state change, if there was one if ( $new_state ) { $problem->state( $new_state ); - $problem->lastupdate( \'ms_current_timestamp()' ); + $problem->lastupdate( \'current_timestamp' ); } # If it's not fixed and they say it's still not been fixed, record time update if ( $c->stash->{been_fixed} eq 'No' && FixMyStreet::DB::Result::Problem->open_states->{$old_state} ) { - $problem->lastupdate( \'ms_current_timestamp()' ); + $problem->lastupdate( \'current_timestamp' ); } # Record questionnaire response @@ -189,7 +189,7 @@ sub submit_standard : Private { my $q = $c->stash->{questionnaire}; $q->update( { - whenanswered => \'ms_current_timestamp()', + whenanswered => \'current_timestamp', ever_reported => $reported, old_state => $old_state, new_state => $c->stash->{been_fixed} eq 'Unknown' ? 'unknown' : ($new_state || $old_state), @@ -210,7 +210,7 @@ sub submit_standard : Private { lang => $c->stash->{lang_code}, cobrand => $c->cobrand->moniker, cobrand_data => '', - confirmed => \'ms_current_timestamp()', + confirmed => \'current_timestamp', anonymous => $problem->anonymous, } ); @@ -234,6 +234,8 @@ sub process_questionnaire : Private { map { $c->stash->{$_} = $c->get_param($_) || '' } qw(been_fixed reported another update); + $c->stash->{update} = Utils::cleanup_text($c->stash->{update}, { allow_multiline => 1 }); + # EHA questionnaires done for you if ($c->cobrand->moniker eq 'emptyhomes') { $c->stash->{another} = $c->stash->{num_questionnaire}==1 ? 'Yes' : 'No'; diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 7b001ee4c..d7cae05d4 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -99,23 +99,30 @@ sub load_problem_or_display_error : Private { my $problem = ( !$id || $id =~ m{\D} ) # is id non-numeric? ? undef # ...don't even search - : $c->cobrand->problems->find( { id => $id } ); + : $c->cobrand->problems->find( { id => $id } ) + or $c->detach( '/page_error_404_not_found', [ _('Unknown problem ID') ] ); # check that the problem is suitable to show. - if ( !$problem || ($problem->state eq 'unconfirmed' && !$c->cobrand->show_unconfirmed_reports) || $problem->state eq 'partial' ) { + # hidden_states includes partial and unconfirmed, but they have specific handling, + # so we check for them first. + if ( $problem->state eq 'partial' ) { $c->detach( '/page_error_404_not_found', [ _('Unknown problem ID') ] ); } - elsif ( $problem->state eq 'hidden' ) { + elsif ( $problem->state eq 'unconfirmed' ) { + $c->detach( '/page_error_404_not_found', [ _('Unknown problem ID') ] ) + unless $c->cobrand->show_unconfirmed_reports ; + } + elsif ( $problem->hidden_states->{ $problem->state } or + (($problem->get_extra_metadata('closure_status')||'') eq 'hidden')) { $c->detach( '/page_error_410_gone', [ _('That report has been removed from FixMyStreet.') ] # ); } elsif ( $problem->non_public ) { if ( !$c->user || $c->user->id != $problem->user->id ) { - my $site_name = Utils::trim_text($c->render_fragment('site-name.html')); $c->detach( '/page_error_403_access_denied', - [ sprintf(_('That report cannot be viewed on %s.'), $site_name) ] # + [ sprintf(_('That report cannot be viewed on %s.'), $c->stash->{site_name}) ] ); } } @@ -242,7 +249,7 @@ sub delete :Local :Args(1) { return $c->res->redirect($uri) unless $p->bodies->{$body->id}; $p->state('hidden'); - $p->lastupdate( \'ms_current_timestamp()' ); + $p->lastupdate( \'current_timestamp' ); $p->update; $c->model('DB::AdminLog')->create( { diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index b540a1961..246facbee 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -93,6 +93,7 @@ sub report_new : Path : Args(0) { $c->forward('check_for_category'); # deal with the user and report and check both are happy + return unless $c->forward('check_form_submitted'); $c->forward('process_user'); $c->forward('process_report'); @@ -106,6 +107,12 @@ sub report_new : Path : Args(0) { # report_new but there's a few workflow differences as we only ever want # to sent JSON back here +sub report_new_test : Path('_test_') : Args(0) { + my ( $self, $c ) = @_; + $c->stash->{template} = 'email_sent.html'; + $c->stash->{email_type} = $c->get_param('email_type'); +} + sub report_new_ajax : Path('mobile') : Args(0) { my ( $self, $c ) = @_; @@ -284,7 +291,7 @@ sub report_import : Path('/import') { } # handle the photo upload - $c->forward( '/photo/process_photo_upload' ); + $c->forward( '/photo/process_photo' ); my $fileid = $c->stash->{upload_fileid}; if ( my $error = $c->stash->{photo_error} ) { push @errors, $error; @@ -883,13 +890,29 @@ sub process_report : Private { $report->bodies_str(-1); } else { # construct the bodies string: - # 'x,x' - x are body IDs that have this category - # 'x,x|y' - x are body IDs that have this category, y body IDs with *no* contact - my $body_string = join( ',', map { $_->body_id } @contacts ); - $body_string .= - '|' . join( ',', map { $_->id } @{ $c->stash->{missing_details_bodies} } ) - if $body_string && @{ $c->stash->{missing_details_bodies} }; + my $body_string = do { + if ( $c->cobrand->can('singleton_bodies_str') && $c->cobrand->singleton_bodies_str ) { + # Cobrands like Zurich can only ever have a single body: 'x', because some functionality + # relies on string comparison against bodies_str. + if (@contacts) { + $contacts[0]->body_id; + } + else { + ''; + } + } + else { + # 'x,x' - x are body IDs that have this category + my $bs = join( ',', map { $_->body_id } @contacts ); + $bs; + }; + }; $report->bodies_str($body_string); + # Record any body IDs which might have meant to match, but had no contact + if ($body_string && @{ $c->stash->{missing_details_bodies} }) { + my $missing = join( ',', map { $_->id } @{ $c->stash->{missing_details_bodies} } ); + $report->bodies_missing($missing); + } } my @extra; @@ -1142,6 +1165,9 @@ sub redirect_or_confirm_creation : Private { return 1; } + my $template = 'problem-confirm.txt'; + $template = 'problem-confirm-not-sending.txt' unless $report->bodies_str; + # otherwise create a confirm token and email it to them. my $data = $c->stash->{token_data} || {}; my $token = $c->model("DB::Token")->create( { @@ -1152,7 +1178,10 @@ sub redirect_or_confirm_creation : Private { } } ); $c->stash->{token_url} = $c->uri_for_email( '/P', $token->token ); - $c->send_email( 'problem-confirm.txt', { + if ($c->cobrand->can('problem_confirm_email_extras')) { + $c->cobrand->problem_confirm_email_extras($report); + } + $c->send_email( $template, { to => [ $report->name ? [ $report->user->email, $report->name ] : $report->user->email ], } ); diff --git a/perllib/FixMyStreet/App/Controller/Report/Update.pm b/perllib/FixMyStreet/App/Controller/Report/Update.pm index 17aec2113..445723fec 100644 --- a/perllib/FixMyStreet/App/Controller/Report/Update.pm +++ b/perllib/FixMyStreet/App/Controller/Report/Update.pm @@ -80,7 +80,7 @@ sub update_problem : Private { $problem->interest_count( \'interest_count + 1' ); } - $problem->lastupdate( \'ms_current_timestamp()' ); + $problem->lastupdate( \'current_timestamp' ); $problem->update; $c->stash->{problem_id} = $problem->id; diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm index 6b0d516a6..407fc625e 100644 --- a/perllib/FixMyStreet/App/Controller/Reports.pm +++ b/perllib/FixMyStreet/App/Controller/Reports.pm @@ -33,6 +33,7 @@ sub index : Path : Args(0) { # Zurich goes straight to map page, with all reports if ( $c->cobrand->moniker eq 'zurich' ) { + $c->forward( 'stash_report_filter_status' ); $c->forward( 'load_and_group_problems' ); my $pins = $c->stash->{pins}; $c->stash->{page} = 'reports'; @@ -121,7 +122,7 @@ sub ward : Path : Args(2) { $c->stash->{stats} = $c->cobrand->get_report_stats(); - my @categories = $c->stash->{body}->contacts->search( undef, { + my @categories = $c->stash->{body}->contacts->not_deleted->search( undef, { columns => [ 'category' ], distinct => 1, order_by => [ 'category' ], @@ -269,9 +270,7 @@ sub rss_ward : Path('/rss/reports') : Args(2) { # Problems sent to a council $c->stash->{type} = 'council_problems'; $c->stash->{title_params} = { COUNCIL => $c->stash->{body}->name }; - # XXX This looks up in both bodies_str and areas, but is only using body ID. - # This will not work properly in any install where body IDs are not === area IDs. - $c->stash->{db_params} = [ $c->stash->{body}->id, $c->stash->{body}->id ]; + $c->stash->{db_params} = [ $c->stash->{body}->id ]; } # Send on to the RSS generation @@ -396,20 +395,20 @@ sub load_and_group_problems : Private { my $not_open = [ FixMyStreet::DB::Result::Problem::fixed_states(), FixMyStreet::DB::Result::Problem::closed_states() ]; if ( $type eq 'new' ) { - $where->{confirmed} = { '>', \"ms_current_timestamp() - INTERVAL '4 week'" }; + $where->{confirmed} = { '>', \"current_timestamp - INTERVAL '4 week'" }; $where->{state} = { 'IN', [ FixMyStreet::DB::Result::Problem::open_states() ] }; } elsif ( $type eq 'older' ) { - $where->{confirmed} = { '<', \"ms_current_timestamp() - INTERVAL '4 week'" }; - $where->{lastupdate} = { '>', \"ms_current_timestamp() - INTERVAL '8 week'" }; + $where->{confirmed} = { '<', \"current_timestamp - INTERVAL '4 week'" }; + $where->{lastupdate} = { '>', \"current_timestamp - INTERVAL '8 week'" }; $where->{state} = { 'IN', [ FixMyStreet::DB::Result::Problem::open_states() ] }; } elsif ( $type eq 'unknown' ) { - $where->{lastupdate} = { '<', \"ms_current_timestamp() - INTERVAL '8 week'" }; + $where->{lastupdate} = { '<', \"current_timestamp - INTERVAL '8 week'" }; $where->{state} = { 'IN', [ FixMyStreet::DB::Result::Problem::open_states() ] }; } elsif ( $type eq 'fixed' ) { - $where->{lastupdate} = { '>', \"ms_current_timestamp() - INTERVAL '8 week'" }; + $where->{lastupdate} = { '>', \"current_timestamp - INTERVAL '8 week'" }; $where->{state} = $not_open; } elsif ( $type eq 'older_fixed' ) { - $where->{lastupdate} = { '<', \"ms_current_timestamp() - INTERVAL '8 week'" }; + $where->{lastupdate} = { '<', \"current_timestamp - INTERVAL '8 week'" }; $where->{state} = $not_open; } @@ -417,29 +416,16 @@ sub load_and_group_problems : Private { $where->{category} = $category; } + my $problems = $c->cobrand->problems; + if ($c->stash->{ward}) { $where->{areas} = { 'like', '%,' . $c->stash->{ward}->{id} . ',%' }; - $where->{bodies_str} = [ - undef, - $c->stash->{body}->id, - { 'like', $c->stash->{body}->id . ',%' }, - { 'like', '%,' . $c->stash->{body}->id }, - ]; + $problems = $problems->to_body($c->stash->{body}); } elsif ($c->stash->{body}) { - # XXX FixMyStreet used to have the following line so that reports not - # currently sent anywhere could still be listed in the appropriate - # (body/area), as they were the same. Now they're not, not sure if - # there's a way to do this easily. - #$where->{areas} = { 'like', '%,' . $c->stash->{body}->id . ',%' }; - $where->{bodies_str} = [ - # undef, - $c->stash->{body}->id, - { 'like', $c->stash->{body}->id . ',%' }, - { 'like', '%,' . $c->stash->{body}->id }, - ]; + $problems = $problems->to_body($c->stash->{body}); } - my $problems = $c->cobrand->problems->search( + $problems = $problems->search( $where, { order_by => $c->cobrand->reports_ordering, @@ -463,7 +449,6 @@ sub load_and_group_problems : Private { } } else { # Add to bodies it was sent to - # XXX Assumes body ID matches "council ID" my $bodies = $problem->bodies_str_ids; foreach ( @$bodies ) { next if $_ != $c->stash->{body}->id; @@ -507,6 +492,9 @@ sub stash_report_filter_status : Private { } elsif ( $status eq 'open' ) { $c->stash->{filter_status} = 'open'; $c->stash->{filter_problem_states} = FixMyStreet::DB::Result::Problem->open_states(); + } elsif ( $status eq 'closed' ) { + $c->stash->{filter_status} = 'closed'; + $c->stash->{filter_problem_states} = FixMyStreet::DB::Result::Problem->closed_states(); } elsif ( $status eq 'fixed' ) { $c->stash->{filter_status} = 'fixed'; $c->stash->{filter_problem_states} = FixMyStreet::DB::Result::Problem->fixed_states(); diff --git a/perllib/FixMyStreet/App/Controller/Rss.pm b/perllib/FixMyStreet/App/Controller/Rss.pm index 7aafc99ff..b817fe326 100755 --- a/perllib/FixMyStreet/App/Controller/Rss.pm +++ b/perllib/FixMyStreet/App/Controller/Rss.pm @@ -264,11 +264,7 @@ sub add_row : Private { (my $link = $alert_type->item_link) =~ s/{{(.*?)}}/$row->{$1}/g; (my $desc = _($alert_type->item_description)) =~ s/{{(.*?)}}/$row->{$1}/g; - my $hashref_restriction = $c->cobrand->site_restriction; - my $base_url = $c->cobrand->base_url; - if ( $hashref_restriction && $hashref_restriction->{bodies_str} && $row->{bodies_str} && $row->{bodies_str} ne $hashref_restriction->{bodies_str} ) { - $base_url = $c->config->{BASE_URL}; - } + my $base_url = $c->cobrand->base_url_for_report($row); my $url = $base_url . $link; my %item = ( diff --git a/perllib/FixMyStreet/App/Controller/Status.pm b/perllib/FixMyStreet/App/Controller/Status.pm new file mode 100755 index 000000000..907fe5456 --- /dev/null +++ b/perllib/FixMyStreet/App/Controller/Status.pm @@ -0,0 +1,70 @@ +package FixMyStreet::App::Controller::Status; +use Moose; +use namespace::autoclean; + +use HTTP::Negotiate; +use JSON; + +BEGIN { extends 'Catalyst::Controller'; } + +=head1 NAME + +FixMyStreet::App::Controller::Status - Catalyst Controller + +=head1 DESCRIPTION + +Status page Catalyst Controller. + +=head1 METHODS + +=cut + +sub index_json : Path('/status.json') : Args(0) { + my ($self, $c) = @_; + $c->forward('index', [ 'json' ]); +} + +sub index : Path : Args(0) { + my ($self, $c, $format) = @_; + + # Fetch summary stats from admin front page + $c->forward('/admin/index'); + + # Fetch git version + $c->forward('/admin/config_page'); + + my $chosen = $format; + unless ($chosen) { + my $variants = [ + ['html', undef, 'text/html', undef, undef, undef, undef], + ['json', undef, 'application/json', undef, undef, undef, undef], + ]; + $chosen = HTTP::Negotiate::choose($variants, $c->req->headers); + $chosen = 'html' unless $chosen; + } + + # TODO Perform health checks here + + if ($chosen eq 'json') { + $c->res->content_type('application/json; charset=utf-8'); + my $data = { + version => $c->stash->{git_version}, + reports => $c->stash->{total_problems_live}, + updates => $c->stash->{comments}{confirmed}, + alerts_confirmed => $c->stash->{alerts}{1}, + alerts_unconfirmed => $c->stash->{alerts}{0}, + questionnaires_sent => $c->stash->{questionnaires}{total}, + questionnaires_answered => $c->stash->{questionnaires}{1}, + bodies => $c->stash->{total_bodies}, + contacts => $c->stash->{contacts}{total}, + }; + my $body = JSON->new->utf8(1)->pretty->encode($data); + $c->res->body($body); + } + + return 1; +} + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/perllib/FixMyStreet/App/Controller/Tokens.pm b/perllib/FixMyStreet/App/Controller/Tokens.pm index 21c269502..ba15162ce 100644 --- a/perllib/FixMyStreet/App/Controller/Tokens.pm +++ b/perllib/FixMyStreet/App/Controller/Tokens.pm @@ -58,7 +58,7 @@ sub confirm_problem : Path('/P') { # check that this email or domain are not the cause of abuse. If so hide it. if ( $problem->is_from_abuser ) { $problem->update( - { state => 'hidden', lastupdate => \'ms_current_timestamp()' } ); + { state => 'hidden', lastupdate => \'current_timestamp' } ); $c->stash->{template} = 'tokens/abuse.html'; return; } @@ -68,7 +68,7 @@ sub confirm_problem : Path('/P') { if ($c->cobrand->moniker eq 'zurich') { $problem->set_extra_metadata( email_confirmed => 1 ); $problem->update( { - confirmed => \'ms_current_timestamp()', + confirmed => \'current_timestamp', } ); if ( $data->{name} || $data->{password} ) { @@ -90,8 +90,8 @@ sub confirm_problem : Path('/P') { $problem->update( { state => 'confirmed', - confirmed => \'ms_current_timestamp()', - lastupdate => \'ms_current_timestamp()', + confirmed => \'current_timestamp', + lastupdate => \'current_timestamp', } ); |