aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/update-schema1
-rw-r--r--db/downgrade_0065---0064.sql14
-rw-r--r--db/schema.sql1
-rw-r--r--db/schema_0065-add-moderation-admin-log.sql13
-rw-r--r--perllib/FixMyStreet/App/Controller/Moderate.pm44
-rw-r--r--perllib/FixMyStreet/DB/Result/Comment.pm24
-rw-r--r--perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm24
-rw-r--r--perllib/FixMyStreet/Roles/Moderation.pm41
-rw-r--r--templates/web/base/admin/report_edit.html4
-rw-r--r--templates/web/base/admin/update_edit.html4
11 files changed, 115 insertions, 65 deletions
diff --git a/bin/update-schema b/bin/update-schema
index 55a052ccc..1e1afa72c 100755
--- a/bin/update-schema
+++ b/bin/update-schema
@@ -212,6 +212,7 @@ else {
# (assuming schema change files are never half-applied, which should be the case)
sub get_db_version {
return 'EMPTY' if ! table_exists('problem');
+ return '0065' if constraint_contains('admin_log_object_type_check', 'moderation');
return '0064' if index_exists('moderation_original_data_problem_id_comment_id_idx');
return '0063' if column_exists('moderation_original_data', 'extra');
return '0062' if column_exists('users', 'created');
diff --git a/db/downgrade_0065---0064.sql b/db/downgrade_0065---0064.sql
new file mode 100644
index 000000000..455627b77
--- /dev/null
+++ b/db/downgrade_0065---0064.sql
@@ -0,0 +1,14 @@
+BEGIN;
+
+DELETE FROM admin_log WHERE object_type = 'moderation';
+
+ALTER TABLE admin_log DROP CONSTRAINT admin_log_object_type_check;
+
+ALTER TABLE admin_log ADD CONSTRAINT admin_log_object_type_check CHECK (
+ object_type = 'problem'
+ OR object_type = 'update'
+ OR object_type = 'user'
+);
+
+COMMIT;
+
diff --git a/db/schema.sql b/db/schema.sql
index d5d63f478..c97e8d585 100644
--- a/db/schema.sql
+++ b/db/schema.sql
@@ -427,6 +427,7 @@ create table admin_log (
object_type = 'problem'
or object_type = 'update'
or object_type = 'user'
+ or object_type = 'moderation'
),
object_id integer not null,
action text not null,
diff --git a/db/schema_0065-add-moderation-admin-log.sql b/db/schema_0065-add-moderation-admin-log.sql
new file mode 100644
index 000000000..9a5385db7
--- /dev/null
+++ b/db/schema_0065-add-moderation-admin-log.sql
@@ -0,0 +1,13 @@
+BEGIN;
+
+ALTER TABLE admin_log DROP CONSTRAINT admin_log_object_type_check;
+
+ALTER TABLE admin_log ADD CONSTRAINT admin_log_object_type_check CHECK (
+ object_type = 'problem'
+ OR object_type = 'update'
+ OR object_type = 'user'
+ OR object_type = 'moderation'
+);
+
+COMMIT;
+
diff --git a/perllib/FixMyStreet/App/Controller/Moderate.pm b/perllib/FixMyStreet/App/Controller/Moderate.pm
index 3ed2022ee..154f09176 100644
--- a/perllib/FixMyStreet/App/Controller/Moderate.pm
+++ b/perllib/FixMyStreet/App/Controller/Moderate.pm
@@ -119,23 +119,32 @@ sub moderating_user_name {
return $user->from_body ? $user->from_body->name : _('an administrator');
}
-sub report_moderate_audit : Private {
- my ($self, $c, @types) = @_;
+sub moderate_log_entry : Private {
+ my ($self, $c, $object_type, @types) = @_;
my $user = $c->user->obj;
my $reason = $c->stash->{'moderation_reason'};
- my $problem = $c->stash->{problem} or die;
+ my $object = $object_type eq 'update' ? $c->stash->{comment} : $c->stash->{problem};
my $types_csv = join ', ' => @types;
+ # We attach the log to the moderation entry if present, or the object if not (hiding)
$c->model('DB::AdminLog')->create({
action => 'moderation',
user => $user,
admin_user => moderating_user_name($user),
- object_id => $problem->id,
- object_type => 'problem',
+ object_id => $c->stash->{history}->id || $object->id,
+ object_type => $c->stash->{history}->id ? 'moderation' : $object_type,
reason => (sprintf '%s (%s)', $reason, $types_csv),
});
+}
+
+sub report_moderate_audit : Private {
+ my ($self, $c, @types) = @_;
+
+ my $problem = $c->stash->{problem} or die;
+
+ $c->forward('moderate_log_entry', [ 'problem', @types ]);
if ($problem->user->email_verified && $c->cobrand->send_moderation_notifications) {
my $token = $c->model("DB::Token")->create({
@@ -143,6 +152,7 @@ sub report_moderate_audit : Private {
data => { id => $problem->id }
});
+ my $types_csv = join ', ' => @types;
$c->send_email( 'problem-moderated.txt', {
to => [ [ $problem->user->email, $problem->name ] ],
types => $types_csv,
@@ -316,27 +326,7 @@ sub moderate_update : Chained('update') : PathPart('') : Args(0) {
$c->forward('moderate_extra'),
$c->forward('moderate_boolean', [ 'photo' ]);
- $c->detach( 'update_moderate_audit', \@types )
-}
-
-sub update_moderate_audit : Private {
- my ($self, $c, @types) = @_;
-
- my $user = $c->user->obj;
- my $reason = $c->stash->{'moderation_reason'};
- my $problem = $c->stash->{problem} or die;
- my $comment = $c->stash->{comment} or die;
-
- my $types_csv = join ', ' => @types;
-
- $c->model('DB::AdminLog')->create({
- action => 'moderation',
- user => $user,
- admin_user => moderating_user_name($user),
- object_id => $comment->id,
- object_type => 'update',
- reason => (sprintf '%s (%s)', $reason, $types_csv),
- });
+ $c->detach('moderate_log_entry', [ 'update', @types ]);
}
sub update_moderate_hide : Private {
@@ -347,7 +337,7 @@ sub update_moderate_hide : Private {
if ($c->get_param('update_hide')) {
$comment->hide;
- $c->detach( 'update_moderate_audit', ['hide'] ); # break chain here.
+ $c->detach('moderate_log_entry', [ 'update', 'hide' ]); # break chain here.
}
return;
}
diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm
index 3a2b7d84b..31e9f3e63 100644
--- a/perllib/FixMyStreet/DB/Result/Comment.pm
+++ b/perllib/FixMyStreet/DB/Result/Comment.pm
@@ -102,6 +102,7 @@ use FixMyStreet::Template;
with 'FixMyStreet::Roles::Abuser',
'FixMyStreet::Roles::Extra',
+ 'FixMyStreet::Roles::Moderation',
'FixMyStreet::Roles::PhotoSet';
my $stz = sub {
@@ -176,17 +177,6 @@ sub url {
return "/report/" . $self->problem_id . '#update_' . $self->id;
}
-=head2 latest_moderation_log_entry
-
-Return most recent ModerationLog object
-
-=cut
-
-sub latest_moderation_log_entry {
- my $self = shift;
- return $self->admin_log_entries->search({ action => 'moderation' }, { order_by => { -desc => 'id' } })->first;
-}
-
__PACKAGE__->has_many(
"admin_log_entries",
"FixMyStreet::DB::Result::AdminLog",
@@ -197,13 +187,6 @@ __PACKAGE__->has_many(
}
);
-sub moderation_history {
- my $self = shift;
- return $self->moderation_original_datas->search({
- problem_id => $self->problem_id,
- }, { order_by => { -desc => 'id' } })->all;
-}
-
# This will return the oldest moderation_original_data, if any.
# The plural can be used to return all entries.
__PACKAGE__->might_have(
@@ -217,6 +200,11 @@ __PACKAGE__->might_have(
cascade_copy => 0, cascade_delete => 1 },
);
+sub moderation_filter {
+ my $self = shift;
+ { problem_id => $self->problem_id };
+}
+
=head2 meta_line
Returns a string to be used on a report update, describing some of the metadata
diff --git a/perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm b/perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm
index 42ff75295..01ae1d6e1 100644
--- a/perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm
+++ b/perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm
@@ -78,6 +78,16 @@ with 'FixMyStreet::Roles::Extra';
__PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn");
__PACKAGE__->rabx_column('extra');
+sub admin_log {
+ my $self = shift;
+ my $rs = $self->result_source->schema->resultset("AdminLog");
+ my $log = $rs->search({
+ object_id => $self->id,
+ object_type => 'moderation',
+ })->first;
+ return $log;
+}
+
sub compare_with {
my ($self, $other) = @_;
if ($self->comment_id) {
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm
index a7884f7d2..a222ea1f6 100644
--- a/perllib/FixMyStreet/DB/Result/Problem.pm
+++ b/perllib/FixMyStreet/DB/Result/Problem.pm
@@ -210,6 +210,7 @@ my $IM = eval {
with 'FixMyStreet::Roles::Abuser',
'FixMyStreet::Roles::Extra',
+ 'FixMyStreet::Roles::Moderation',
'FixMyStreet::Roles::Translatable',
'FixMyStreet::Roles::PhotoSet';
@@ -962,24 +963,6 @@ sub as_hashref {
return $out;
}
-=head2 latest_moderation_log_entry
-
-Return most recent ModerationLog object
-
-=cut
-
-sub latest_moderation_log_entry {
- my $self = shift;
- return $self->admin_log_entries->search({ action => 'moderation' }, { order_by => { -desc => 'id' } })->first;
-}
-
-sub moderation_history {
- my $self = shift;
- return $self->moderation_original_datas->search({
- comment_id => undef,
- }, { order_by => { -desc => 'id' } })->all;
-}
-
__PACKAGE__->has_many(
"admin_log_entries",
"FixMyStreet::DB::Result::AdminLog",
@@ -990,6 +973,11 @@ __PACKAGE__->has_many(
}
);
+sub moderation_filter {
+ my $self = shift;
+ { comment_id => undef };
+}
+
sub get_time_spent {
my $self = shift;
my $admin_logs = $self->admin_log_entries->search({},
diff --git a/perllib/FixMyStreet/Roles/Moderation.pm b/perllib/FixMyStreet/Roles/Moderation.pm
new file mode 100644
index 000000000..f43b65208
--- /dev/null
+++ b/perllib/FixMyStreet/Roles/Moderation.pm
@@ -0,0 +1,41 @@
+package FixMyStreet::Roles::Moderation;
+use Moo::Role;
+
+=head2 latest_moderation_log_entry
+
+Return most recent AdminLog object concerning moderation
+
+=cut
+
+sub latest_moderation_log_entry {
+ my $self = shift;
+
+ my $latest = $self->moderation_original_datas->search(
+ $self->moderation_filter,
+ { order_by => { -desc => 'id' } })->first;
+ return unless $latest;
+
+ my $rs = $self->result_source->schema->resultset("AdminLog");
+ my $log = $rs->search({
+ object_id => $latest->id,
+ object_type => 'moderation',
+ })->first;
+ return $log if $log;
+
+ return $self->admin_log_entries->search({ action => 'moderation' }, { order_by => { -desc => 'id' } })->first;
+}
+
+=head2 moderation_history
+
+Returns all moderation history, most recent first.
+
+=cut
+
+sub moderation_history {
+ my $self = shift;
+ return $self->moderation_original_datas->search(
+ $self->moderation_filter,
+ { order_by => { -desc => 'id' } })->all;
+}
+
+1;
diff --git a/templates/web/base/admin/report_edit.html b/templates/web/base/admin/report_edit.html
index a38bacb00..175863549 100644
--- a/templates/web/base/admin/report_edit.html
+++ b/templates/web/base/admin/report_edit.html
@@ -190,7 +190,9 @@ class="admin-offsite-link">[% problem.latitude %], [% problem.longitude %]</a>
<ul>
[% FOR history IN moderation_history %]
[% SET diff = history.compare_with(last_history) %]
- <li>[% PROCESS format_time time=history.created %]:
+ [% SET log = history.admin_log %]
+ <li><i>[% tprintf(loc('Moderated by %s at %s'), log.user.name OR loc('an administrator'), prettify_dt(history.created)) %]
+ [%~ IF log.reason %]<br>“[% log.reason %]”[% END %]</i>
[% IF diff.title %]<br>[% loc('Subject:') %] [% diff.title %][% END %]
[% IF diff.detail %]<br>[% loc('Details:') %] [% diff.detail %][% END %]
[% IF diff.photo %]<br>[% loc('Photo') %]: [% diff.photo %][% END %]
diff --git a/templates/web/base/admin/update_edit.html b/templates/web/base/admin/update_edit.html
index d997b89e8..fca9b1904 100644
--- a/templates/web/base/admin/update_edit.html
+++ b/templates/web/base/admin/update_edit.html
@@ -88,7 +88,9 @@
<ul>
[% FOR history IN moderation_history %]
[% SET diff = history.compare_with(last_history) %]
- <li>[% PROCESS format_time time=history.created %]:
+ [% SET log = history.admin_log %]
+ <li><i>[% tprintf(loc('Moderated by %s at %s'), log.user.name OR loc('an administrator'), prettify_dt(history.created)) %]
+ [%~ IF log.reason %]<br>“[% log.reason %]”[% END %]</i>
[% IF diff.detail %]<br>[% loc('Text:') %] [% diff.detail %][% END %]
[% IF diff.photo %]<br>[% loc('Photo') %]: [% diff.photo %][% END %]
[% IF diff.anonymous %]<br>[% loc('Anonymous:') %] [% diff.anonymous %][% END %]