aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App/Controller/Admin.pm
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Admin.pm')
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm222
1 files changed, 148 insertions, 74 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