diff options
Diffstat (limited to 'perllib')
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Around.pm | 2 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Auth.pm | 5 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/My.pm | 75 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 8 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Reports.pm | 10 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Root.pm | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/Comment.pm | 88 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/User.pm | 2 |
8 files changed, 179 insertions, 12 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Around.pm b/perllib/FixMyStreet/App/Controller/Around.pm index b4f94bb35..96854b17b 100644 --- a/perllib/FixMyStreet/App/Controller/Around.pm +++ b/perllib/FixMyStreet/App/Controller/Around.pm @@ -291,6 +291,8 @@ sub ajax : Path('/ajax') { # assume this is not cacheable - may need to be more fine-grained later $c->res->header( 'Cache_Control' => 'max-age=0' ); + $c->stash->{page} = 'around'; # Needed by _item.html + # how far back should we go? my $all_pins = $c->get_param('all_pins') ? 1 : undef; my $interval = $all_pins ? undef : $c->cobrand->on_map_default_max_pin_age; diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm index c448f8749..6e8057723 100644 --- a/perllib/FixMyStreet/App/Controller/Auth.pm +++ b/perllib/FixMyStreet/App/Controller/Auth.pm @@ -516,11 +516,12 @@ sub check_csrf_token : Private { $token =~ s/ /+/g; my ($time) = $token =~ /^(\d+)-[0-9a-zA-Z+\/]+$/; $c->stash->{csrf_time} = $time; + my $gen_token = $c->forward('get_csrf_token'); + delete $c->stash->{csrf_time}; $c->detach('no_csrf_token') unless $time && $time > time() - 3600 - && $token eq $c->forward('get_csrf_token'); - delete $c->stash->{csrf_time}; + && $token eq $gen_token; } sub no_csrf_token : Private { diff --git a/perllib/FixMyStreet/App/Controller/My.pm b/perllib/FixMyStreet/App/Controller/My.pm index 51f1687ee..c26cdd5c8 100644 --- a/perllib/FixMyStreet/App/Controller/My.pm +++ b/perllib/FixMyStreet/App/Controller/My.pm @@ -3,6 +3,7 @@ use Moose; use namespace::autoclean; use JSON::MaybeXS; +use List::MoreUtils qw(first_index); BEGIN { extends 'Catalyst::Controller'; } @@ -30,8 +31,11 @@ sub begin : Private { sub my : Path : Args(0) { my ( $self, $c ) = @_; + $c->forward('/auth/get_csrf_token'); + $c->stash->{problems_rs} = $c->cobrand->problems->search( { user_id => $c->user->id }); + $c->forward('/reports/stash_report_sort', [ 'created-desc' ]); $c->forward('get_problems'); if ($c->get_param('ajax')) { $c->detach('/reports/ajax', [ 'my/_problem-list.html' ]); @@ -43,21 +47,54 @@ sub my : Path : Args(0) { sub planned : Local : Args(0) { my ( $self, $c ) = @_; + $c->forward('/auth/get_csrf_token'); + $c->detach('/page_error_403_access_denied', []) unless $c->user->has_body_permission_to('planned_reports'); $c->stash->{problems_rs} = $c->user->active_planned_reports; + $c->forward('planned_reorder'); + $c->forward('/reports/stash_report_sort', [ 'shortlist' ]); $c->forward('get_problems'); $c->forward('setup_page_data'); } +sub planned_reorder : Private { + my ($self, $c) = @_; + + my @extra = grep { /^shortlist-(up|down|\d+)$/ } keys %{$c->req->params}; + return unless @extra; + my ($reorder) = $extra[0] =~ /^shortlist-(up|down|\d+)$/; + + my @shortlist = sort by_shortlisted $c->stash->{problems_rs}->all; + + # Find where moving problem ID is + my $id = $c->get_param('id') || return; + my $curr_index = first_index { $_->id == $id } @shortlist; + return unless $curr_index > -1; + + if ($reorder eq 'up' && $curr_index > 0) { + @shortlist[$curr_index-1,$curr_index] = @shortlist[$curr_index,$curr_index-1]; + } elsif ($reorder eq 'down' && $curr_index < @shortlist-1) { + @shortlist[$curr_index,$curr_index+1] = @shortlist[$curr_index+1,$curr_index]; + } elsif ($reorder >= 0 && $reorder <= @shortlist-1) { # Must be an index to move it + @shortlist[$curr_index,$reorder] = @shortlist[$reorder,$curr_index]; + } + + # Store new ordering + my $i = 1; + foreach (@shortlist) { + $_->set_extra_metadata('order', $i++); + $_->update; + } +} + sub get_problems : Private { my ($self, $c) = @_; my $p_page = $c->get_param('p') || 1; $c->forward( '/reports/stash_report_filter_status' ); - $c->forward('/reports/stash_report_sort', [ 'created-desc' ]); my $pins = []; my $problems = []; @@ -73,9 +110,12 @@ sub get_problems : Private { $c->stash->{filter_category} = $categories; } + my $rows = 50; + $rows = 5000 if $c->stash->{sort_key} eq 'shortlist'; # Want all reports + my $rs = $c->stash->{problems_rs}->search( $params, { order_by => $c->stash->{sort_order}, - rows => 50 + rows => $rows, } )->include_comment_counts->page( $p_page ); while ( my $problem = $rs->next ) { @@ -83,6 +123,9 @@ sub get_problems : Private { push @$pins, $problem->pin_data($c, 'my', private => 1); push @$problems, $problem; } + + @$problems = sort by_shortlisted @$problems if $c->stash->{sort_key} eq 'shortlist'; + $c->stash->{problems_pager} = $rs->pager; $c->stash->{problems} = $problems; $c->stash->{pins} = $pins; @@ -134,27 +177,45 @@ sub planned_change : Path('planned/change') { my ($self, $c) = @_; $c->forward('/auth/check_csrf_token'); + $c->go('planned') if grep { /^shortlist-(up|down|\d+)$/ } keys %{$c->req->params}; + my $id = $c->get_param('id'); $c->forward( '/report/load_problem_or_display_error', [ $id ] ); - my $change = $c->get_param('change'); + my $add = $c->get_param('shortlist-add'); + my $remove = $c->get_param('shortlist-remove'); $c->detach('/page_error_403_access_denied', []) - unless $change && $change =~ /add|remove/; + unless $add || $remove; - if ($change eq 'add') { + if ($add) { $c->user->add_to_planned_reports($c->stash->{problem}); - } elsif ($change eq 'remove') { + } elsif ($remove) { $c->user->remove_from_planned_reports($c->stash->{problem}); } if ($c->get_param('ajax')) { $c->res->content_type('application/json; charset=utf-8'); - $c->res->body(encode_json({ outcome => $change })); + $c->res->body(encode_json({ outcome => $add ? 'add' : 'remove' })); } else { $c->res->redirect( $c->uri_for_action('report/display', $id) ); } } +sub by_shortlisted { + my $a_order = $a->get_extra_metadata('order') || 0; + my $b_order = $b->get_extra_metadata('order') || 0; + if ($a_order && $b_order) { + $a_order <=> $b_order; + } elsif ($a_order) { + -1; # Want non-ordered to come last + } elsif ($b_order) { + 1; # Want non-ordered to come last + } else { + # Default to order added to planned reports + $a->user_planned_reports->first->id <=> $b->user_planned_reports->first->id; + } +} + __PACKAGE__->meta->make_immutable; 1; diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index e2569d2e9..6d90b6ee9 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -83,6 +83,14 @@ sub report_new : Path : Args(0) { $c->forward('initialize_report'); $c->forward('/auth/get_csrf_token'); + my @shortlist = grep { /^shortlist-(add|remove)-(\d+)$/ } keys %{$c->req->params}; + if (@shortlist) { + my ($cmd, $id) = $shortlist[0] =~ /^shortlist-(add|remove)-(\d+)$/; + $c->req->params->{id} = $id; + $c->req->params->{"shortlist-$cmd"} = 1; + $c->detach('/my/planned_change'); + } + # work out the location for this report and do some checks # Also show map if we're just updating the filters return $c->forward('redirect_to_around') diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm index f2c43b5ee..2635b7b7a 100644 --- a/perllib/FixMyStreet/App/Controller/Reports.pm +++ b/perllib/FixMyStreet/App/Controller/Reports.pm @@ -108,6 +108,8 @@ Show the summary page for a particular ward. sub ward : Path : Args(2) { my ( $self, $c, $body, $ward ) = @_; + $c->forward('/auth/get_csrf_token'); + $c->forward( 'body_check', [ $body ] ); $c->forward( 'ward_check', [ $ward ] ) if $ward; @@ -513,13 +515,17 @@ sub stash_report_sort : Private { ); my $sort = $c->get_param('sort') || $default; - $sort = $default unless $sort =~ /^((updated|created)-(desc|asc)|comments-desc)$/; + $sort = $default unless $sort =~ /^((updated|created)-(desc|asc)|comments-desc|shortlist)$/; + $c->stash->{sort_key} = $sort; + + # Going to do this sorting code-side + $sort = 'created-desc' if $sort eq 'shortlist'; + $sort =~ /^(updated|created|comments)-(desc|asc)$/; my $order_by = $types{$1} || $1; my $dir = $2; $order_by = { -desc => $order_by } if $dir eq 'desc'; - $c->stash->{sort_key} = $sort; $c->stash->{sort_order} = $order_by; return 1; } diff --git a/perllib/FixMyStreet/App/Controller/Root.pm b/perllib/FixMyStreet/App/Controller/Root.pm index 20a871b17..4f098dfc3 100644 --- a/perllib/FixMyStreet/App/Controller/Root.pm +++ b/perllib/FixMyStreet/App/Controller/Root.pm @@ -58,6 +58,7 @@ sub index : Path : Args(0) { return; } + $c->forward('/auth/get_csrf_token'); } =head2 default diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm index f5601639a..fb41bc7f0 100644 --- a/perllib/FixMyStreet/DB/Result/Comment.pm +++ b/perllib/FixMyStreet/DB/Result/Comment.pm @@ -6,6 +6,7 @@ package FixMyStreet::DB::Result::Comment; use strict; use warnings; +use FixMyStreet::Template; use base 'DBIx::Class::Core'; __PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn"); @@ -199,7 +200,7 @@ __PACKAGE__->has_many( "admin_log_entries", "FixMyStreet::DB::Result::AdminLog", { "foreign.object_id" => "self.id" }, - { + { cascade_copy => 0, cascade_delete => 0, where => { 'object_type' => 'update' }, } @@ -223,4 +224,89 @@ __PACKAGE__->might_have( { cascade_copy => 0, cascade_delete => 1 }, ); +=head2 meta_line + +Returns a string to be used on a report update, describing some of the metadata +about an update + +=cut + +sub meta_line { + my ( $self, $c ) = @_; + + my $meta = ''; + + $c->stash->{last_state} ||= ''; + + if ($self->anonymous or !$self->name) { + $meta = sprintf( _( 'Posted anonymously at %s' ), Utils::prettify_dt( $self->confirmed ) ) + } elsif ($self->user->from_body) { + my $user_name = FixMyStreet::Template::html_filter($self->user->name); + my $body = $self->user->body; + if ($body eq 'Bromley Council') { + $body = "$body <img src='/cobrands/bromley/favicon.png' alt=''>"; + } + if ($c->user_exists and $c->user->has_permission_to('view_body_contribute_details', $self->problem->bodies_str_ids)) { + $meta = sprintf( _( 'Posted by <strong>%s</strong> (%s) at %s' ), $body, $user_name, Utils::prettify_dt( $self->confirmed ) ); + } else { + $meta = sprintf( _( 'Posted by <strong>%s</strong> at %s' ), $body, Utils::prettify_dt( $self->confirmed ) ); + } + } else { + $meta = sprintf( _( 'Posted by %s at %s' ), FixMyStreet::Template::html_filter($self->name), Utils::prettify_dt( $self->confirmed ) ) + } + + my $update_state = ''; + + if ($self->mark_fixed) { + $update_state = _( 'marked as fixed' ); + } elsif ($self->mark_open) { + $update_state = _( 'reopened' ); + } elsif ($self->problem_state) { + my $state = $self->problem_state_display; + + if ($state eq 'confirmed') { + if ($c->stash->{last_state}) { + $update_state = _( 'reopened' ) + } + } elsif ($state eq 'investigating') { + $update_state = _( 'marked as investigating' ) + } elsif ($state eq 'planned') { + $update_state = _( 'marked as planned' ) + } elsif ($state eq 'in progress') { + $update_state = _( 'marked as in progress' ) + } elsif ($state eq 'action scheduled') { + $update_state = _( 'marked as action scheduled' ) + } elsif ($state eq 'closed') { + $update_state = _( 'marked as closed' ) + } elsif ($state eq 'fixed') { + $update_state = _( 'marked as fixed' ) + } elsif ($state eq 'unable to fix') { + $update_state = _( 'marked as unable to fix' ) + } elsif ($state eq 'not responsible') { + $update_state = _( "marked as not the council's responsibility" ) + } elsif ($state eq 'duplicate') { + $update_state = _( 'closed as a duplicate report' ) + } elsif ($state eq 'internal referral') { + $update_state = _( 'marked as an internal referral' ) + } + + if ($c->cobrand->moniker eq 'bromley' || $self->problem->bodies_str eq '2482') { + if ($state eq 'unable to fix') { + $update_state = 'marked as no further action'; + } elsif ($state eq 'not responsible') { + $update_state = 'marked as third party responsibility' + } + } + + } + + if ($update_state ne $c->stash->{last_state} and $update_state) { + $meta .= ", $update_state"; + } + + $c->stash->{last_state} = $update_state; + + return $meta; +}; + 1; diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index 135f9b4a5..cf6de9a76 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -382,6 +382,8 @@ around add_to_planned_reports => sub { around remove_from_planned_reports => sub { my ($orig, $self, $report) = @_; $self->user_planned_reports->active->for_report($report->id)->remove(); + $report->unset_extra_metadata('order'); + $report->update; }; sub active_planned_reports { |