diff options
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Admin.pm')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 222 |
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 |