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.pm222
-rw-r--r--perllib/FixMyStreet/App/Controller/Around.pm7
-rw-r--r--perllib/FixMyStreet/App/Controller/Auth.pm13
-rw-r--r--perllib/FixMyStreet/App/Controller/Contact.pm15
-rw-r--r--perllib/FixMyStreet/App/Controller/Dashboard.pm16
-rw-r--r--perllib/FixMyStreet/App/Controller/Moderate.pm4
-rw-r--r--perllib/FixMyStreet/App/Controller/My.pm14
-rw-r--r--perllib/FixMyStreet/App/Controller/Photo.pm163
-rwxr-xr-xperllib/FixMyStreet/App/Controller/Questionnaire.pm14
-rw-r--r--perllib/FixMyStreet/App/Controller/Report.pm19
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/New.pm45
-rw-r--r--perllib/FixMyStreet/App/Controller/Report/Update.pm2
-rw-r--r--perllib/FixMyStreet/App/Controller/Reports.pm46
-rwxr-xr-xperllib/FixMyStreet/App/Controller/Rss.pm6
-rwxr-xr-xperllib/FixMyStreet/App/Controller/Status.pm70
-rw-r--r--perllib/FixMyStreet/App/Controller/Tokens.pm8
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',
}
);