use utf8;
package FixMyStreet::DB::Result::ModerationOriginalData;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
use strict;
use warnings;
use base 'DBIx::Class::Core';
__PACKAGE__->load_components(
"FilterColumn",
"FixMyStreet::InflateColumn::DateTime",
"EncodedColumn",
);
__PACKAGE__->table("moderation_original_data");
__PACKAGE__->add_columns(
"id",
{
data_type => "integer",
is_auto_increment => 1,
is_nullable => 0,
sequence => "moderation_original_data_id_seq",
},
"problem_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"comment_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
"title",
{ data_type => "text", is_nullable => 1 },
"detail",
{ data_type => "text", is_nullable => 1 },
"photo",
{ data_type => "bytea", is_nullable => 1 },
"anonymous",
{ data_type => "boolean", is_nullable => 0 },
"created",
{
data_type => "timestamp",
default_value => \"current_timestamp",
is_nullable => 0,
original => { default_value => \"now()" },
},
"extra",
{ data_type => "text", is_nullable => 1 },
"category",
{ data_type => "text", is_nullable => 1 },
"latitude",
{ data_type => "double precision", is_nullable => 1 },
"longitude",
{ data_type => "double precision", is_nullable => 1 },
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->belongs_to(
"comment",
"FixMyStreet::DB::Result::Comment",
{ id => "comment_id" },
{
is_deferrable => 0,
join_type => "LEFT",
on_delete => "CASCADE,",
on_update => "NO ACTION",
},
);
__PACKAGE__->belongs_to(
"problem",
"FixMyStreet::DB::Result::Problem",
{ id => "problem_id" },
{ is_deferrable => 0, on_delete => "CASCADE,", on_update => "NO ACTION" },
);
# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:03:14
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:jOD21ppyp9e1e/pVa/RB9g
use Moo;
use Text::Diff;
use Data::Dumper;
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) {
my $new_detail = $other->can('text') ? $other->text : $other->detail;
return {
detail => string_diff($self->detail, $new_detail),
photo => $self->compare_photo($other),
anonymous => $self->compare_anonymous($other),
extra => $self->compare_extra($other),
};
}
return {
title => string_diff($self->title, $other->title),
detail => string_diff($self->detail, $other->detail),
photo => $self->compare_photo($other),
anonymous => $self->compare_anonymous($other),
coords => $self->compare_coords($other),
category => string_diff($self->category, $other->category, single => 1),
extra => $self->compare_extra($other),
}
}
sub compare_anonymous {
my ($self, $other) = @_;
string_diff(
$self->anonymous ? _('Yes') : _('No'),
$other->anonymous ? _('Yes') : _('No'),
);
}
sub compare_coords {
my ($self, $other) = @_;
return '' unless $self->latitude && $self->longitude;
my $old = join ',', $self->latitude, $self->longitude;
my $new = join ',', $other->latitude, $other->longitude;
string_diff($old, $new, single => 1);
}
sub compare_photo {
my ($self, $other) = @_;
my $old = $self->photo || '';
my $new = $other->photo || '';
return '' if $old eq $new;
$old = [ split /,/, $old ];
$new = [ split /,/, $new ];
my $diff = Algorithm::Diff->new( $old, $new );
my (@added, @deleted);
while ( $diff->Next ) {
next if $diff->Same;
push @deleted, $diff->Items(1);
push @added, $diff->Items(2);
}
return (join ', ', map {
"$_";
} @deleted) . (join ', ', map {
"$_";
} @added);
}
sub compare_extra {
my ($self, $other) = @_;
my $old = $self->get_extra_metadata;
my $new = $other->get_extra_metadata;
my $both = { %$old, %$new };
my @all_keys = sort keys %$both;
my @s;
foreach (@all_keys) {
if ($old->{$_} && $new->{$_}) {
push @s, string_diff("$_ = $old->{$_}", "$_ = $new->{$_}");
} elsif ($new->{$_}) {
push @s, string_diff("", "$_ = $new->{$_}");
} else {
push @s, string_diff("$_ = $old->{$_}", "");
}
}
return join ', ', grep { $_ } @s;
}
sub extra_diff {
my ($self, $other, $key) = @_;
my $o = $self->get_extra_metadata($key);
my $n = $other->get_extra_metadata($key);
return string_diff($o, $n);
}
sub string_diff {
my ($old, $new, %options) = @_;
return '' if $old eq $new;
$old = FixMyStreet::Template::html_filter($old);
$new = FixMyStreet::Template::html_filter($new);
if ($options{single}) {
return unless $old;
$old = [ $old ];
$new = [ $new ];
}
$old = [ split //, $old ] unless ref $old;
$new = [ split //, $new ] unless ref $new;
my $diff = Algorithm::Diff->new( $old, $new );
my $string;
while ($diff->Next) {
my $d = $diff->Diff;
if ($d & 1) {
my $deleted = join '', $diff->Items(1);
$string .= "$deleted";
}
my $inserted = join '', $diff->Items(2);
if ($d & 2) {
$string .= "$inserted";
} else {
$string .= $inserted;
}
}
return $string;
}
1;