aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/DB
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/DB')
-rw-r--r--perllib/FixMyStreet/DB/Factories.pm34
-rw-r--r--perllib/FixMyStreet/DB/RABXColumn.pm12
-rw-r--r--perllib/FixMyStreet/DB/Result/Abuse.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/AdminLog.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/Alert.pm21
-rw-r--r--perllib/FixMyStreet/DB/Result/AlertSent.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/AlertType.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/Body.pm60
-rw-r--r--perllib/FixMyStreet/DB/Result/BodyArea.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/Comment.pm128
-rw-r--r--perllib/FixMyStreet/DB/Result/Contact.pm31
-rw-r--r--perllib/FixMyStreet/DB/Result/ContactDefectType.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/ContactResponsePriority.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/ContactResponseTemplate.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/ContactsHistory.pm14
-rw-r--r--perllib/FixMyStreet/DB/Result/DefectType.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm161
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm149
-rw-r--r--perllib/FixMyStreet/DB/Result/Questionnaire.pm26
-rw-r--r--perllib/FixMyStreet/DB/Result/ReportExtraField.pm (renamed from perllib/FixMyStreet/DB/Result/ReportExtraFields.pm)12
-rw-r--r--perllib/FixMyStreet/DB/Result/ResponsePriority.pm14
-rw-r--r--perllib/FixMyStreet/DB/Result/ResponseTemplate.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/Secret.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/Session.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/State.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/Token.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/Translation.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/User.pm104
-rw-r--r--perllib/FixMyStreet/DB/Result/UserBodyPermission.pm10
-rw-r--r--perllib/FixMyStreet/DB/Result/UserPlannedReport.pm10
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Body.pm87
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Nearby.pm23
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Problem.pm43
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/ReportExtraField.pm (renamed from perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm)2
34 files changed, 777 insertions, 314 deletions
diff --git a/perllib/FixMyStreet/DB/Factories.pm b/perllib/FixMyStreet/DB/Factories.pm
index 56cff280b..5af9ed38f 100644
--- a/perllib/FixMyStreet/DB/Factories.pm
+++ b/perllib/FixMyStreet/DB/Factories.pm
@@ -94,9 +94,25 @@ sub data {
my $self = shift;
my %titles = (
+ 'Abandoned vehicles' => ['Car on pavement, has been there for months', 'Silver car outside house, never used'],
+ 'Bus stops' => ['Bus stop sign wonky', 'Information board broken'],
+ 'Dog fouling' => ['Bad dog fouling in alley way', 'Inconsiderate dog owner' ],
+ 'Flyposting' => ['Fence by road covered in posters', 'Under the bridge is a poster haven'],
+ 'Flytipping' => ['Flytipping on country lane', 'Ten bags of rubbish'],
+ 'Footpath/bridleway away from road' => ['Vehicle blocking footpath'],
+ 'Graffiti' => ['Graffiti', 'Graffiti', 'Offensive graffiti', 'Graffiti on the bridge', 'Remove graffiti'],
+ 'Parks/landscapes' => ['Full litter bins', 'Allotment gate needs repair'],
+ 'Pavements' => ['Hedge encroaching pavement', 'Many cracked slabs on street corner'],
'Potholes' => ['Deep pothole', 'Small pothole', 'Pothole in cycle lane', 'Pothole on busy pavement', 'Large pothole', 'Sinking manhole'],
+ 'Public toilets' => ['Door will not open'],
+ 'Roads/highways' => ['Restricted sight line by zig-zag lines', 'Missing lane markings'],
+ 'Road traffic signs' => ['Bent sign', 'Zebra crossing', 'Bollard missing'],
+ 'Rubbish (refuse and recycling)' => ['Missing bin', 'Bags left uncollected'],
+ 'Street cleaning' => ['Two abandoned trollies', 'Yet more litter'],
'Street lighting' => ['Faulty light', 'Street light not working', 'Lights out in tunnel', 'Light not coming on', 'Light not going off'],
- 'Graffiti' => ['Graffiti', 'Graffiti', 'Offensive graffiti', 'Graffiti on the bridge', 'Remove graffiti'],
+ 'Street nameplates' => ['Broken nameplate', 'Missing nameplate'],
+ 'Traffic lights' => ['Out of sync lights', 'Always on green', 'Broken light'],
+ 'Trees' => ['Young tree damaged', 'Tree looks dangerous in wind'],
'Other' => ['Loose drain cover', 'Flytipping on country lane', 'Vehicle blocking footpath', 'Hedge encroaching pavement', 'Full litter bins'],
);
my %photos = (
@@ -171,8 +187,8 @@ sub create_problem {
$params->{latitude} += rand(2 * $inaccurate_km) - $inaccurate_km;
$params->{longitude} += rand(3 * $inaccurate_km) - 1.5 * $inaccurate_km,
- $params->{title} = $titles->[$rand];
- $params->{detail} = $descs->[$rand];
+ $params->{title} ||= $titles->[$rand];
+ $params->{detail} ||= $descs->[$rand] || 'Please deal with this issue, thank you.';
$params->{photo_id} = $photo;
$params->{confirmed} = DateTime::Format::Pg->format_datetime($params->{confirmed});
return $self->create($params);
@@ -183,7 +199,7 @@ sub create_problem {
package FixMyStreet::DB::Factory::Body;
use parent -norequire, "FixMyStreet::DB::Factory::Base";
-use mySociety::MaPit;
+use FixMyStreet::MapIt;
__PACKAGE__->resultset(FixMyStreet::DB->resultset("Body"));
@@ -192,7 +208,7 @@ __PACKAGE__->exclude(['area_id', 'categories']);
__PACKAGE__->fields({
name => __PACKAGE__->callback(sub {
my $area_id = shift->get('area_id');
- my $area = mySociety::MaPit::call('area', $area_id);
+ my $area = FixMyStreet::MapIt::call('area', $area_id);
$area->{name};
}),
body_areas => __PACKAGE__->callback(sub {
@@ -212,7 +228,7 @@ sub key_field { 'id' }
package FixMyStreet::DB::Factory::Contact;
-use parent "DBIx::Class::Factory";
+use parent -norequire, "FixMyStreet::DB::Factory::Base";
__PACKAGE__->resultset(FixMyStreet::DB->resultset("Contact"));
@@ -224,8 +240,8 @@ __PACKAGE__->fields({
category => 'Other',
email => __PACKAGE__->callback(sub {
my $category = shift->get('category');
- (my $email = lc $_) =~ s/ /-/g;
- lc $category . '@example.org';
+ (my $email = lc $category) =~ s/ /-/g;
+ $email . '@example.org';
}),
state => 'confirmed',
editor => 'Factory',
@@ -233,6 +249,8 @@ __PACKAGE__->fields({
note => 'Created by factory',
});
+sub key_field { 'id' }
+
#######################
package FixMyStreet::DB::Factory::ResponseTemplate;
diff --git a/perllib/FixMyStreet/DB/RABXColumn.pm b/perllib/FixMyStreet/DB/RABXColumn.pm
index 5f1583018..d14b48dc8 100644
--- a/perllib/FixMyStreet/DB/RABXColumn.pm
+++ b/perllib/FixMyStreet/DB/RABXColumn.pm
@@ -59,7 +59,6 @@ sub rabx_column {
my $self = shift;
my $ser = shift;
return undef unless defined $ser;
- utf8::encode($ser) if utf8::is_utf8($ser);
my $h = new IO::String($ser);
return RABX::wire_rd($h);
},
@@ -78,18 +77,23 @@ sub rabx_column {
$RABX_COLUMNS{ _get_class_identifier($class) }{$col} = 1;
}
+# The underlying column should always be UTF-8 encoded bytes.
+sub get_column {
+ my ($self, $col) = @_;
+ my $res = $self->next::method ($col);
+ utf8::encode($res) if $RABX_COLUMNS{_get_class_identifier($self)}{$col} && utf8::is_utf8($res);
+ return $res;
+}
sub set_filtered_column {
my ($self, $col, $val) = @_;
- my $class = ref $self;
-
# because filtered objects may be expensive to marshall for storage there
# is a cache that attempts to detect if they have changed or not. For us
# this cache breaks things and our marshalling is cheap, so clear it when
# trying set a column.
delete $self->{_filtered_column}{$col}
- if $RABX_COLUMNS{ _get_class_identifier($class) }{$col};
+ if $RABX_COLUMNS{ _get_class_identifier($self) }{$col};
return $self->next::method($col, $val);
}
diff --git a/perllib/FixMyStreet/DB/Result/Abuse.pm b/perllib/FixMyStreet/DB/Result/Abuse.pm
index e8e554afa..7818eb743 100644
--- a/perllib/FixMyStreet/DB/Result/Abuse.pm
+++ b/perllib/FixMyStreet/DB/Result/Abuse.pm
@@ -8,14 +8,18 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("abuse");
__PACKAGE__->add_columns("email", { data_type => "text", is_nullable => 0 });
__PACKAGE__->set_primary_key("email");
-# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-03-08 17:19:55
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:PnQhGMx+ktK++3gWOMJBpQ
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:6XdWpymMMUEC4WT9Yh0RLw
# You can replace this text with custom code or comments, and it will be preserved on regeneration
1;
diff --git a/perllib/FixMyStreet/DB/Result/AdminLog.pm b/perllib/FixMyStreet/DB/Result/AdminLog.pm
index 1c9bd3a63..221690405 100644
--- a/perllib/FixMyStreet/DB/Result/AdminLog.pm
+++ b/perllib/FixMyStreet/DB/Result/AdminLog.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("admin_log");
__PACKAGE__->add_columns(
"id",
@@ -54,7 +58,7 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2016-07-20 14:38:36
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:y2xZ4BDv7H+f4vbIZyNflw
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BLPP1KitphuY56ptaXhzgg
1;
diff --git a/perllib/FixMyStreet/DB/Result/Alert.pm b/perllib/FixMyStreet/DB/Result/Alert.pm
index 2a52a7bca..8979fa338 100644
--- a/perllib/FixMyStreet/DB/Result/Alert.pm
+++ b/perllib/FixMyStreet/DB/Result/Alert.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("alert");
__PACKAGE__->add_columns(
"id",
@@ -65,8 +69,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2015-08-13 16:33:38
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:5RNyB430T8PqtFlmGV/MUg
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:pWmsXAFvvjr4x1Q3Zsu4Cg
# You can replace this text with custom code or comments, and it will be preserved on regeneration
@@ -75,17 +79,6 @@ use namespace::clean -except => [ 'meta' ];
with 'FixMyStreet::Roles::Abuser';
-my $stz = sub {
- my ( $orig, $self ) = ( shift, shift );
- my $s = $self->$orig(@_);
- return $s unless $s && UNIVERSAL::isa($s, "DateTime");
- FixMyStreet->set_time_zone($s);
- return $s;
-};
-
-around whensubscribed => $stz;
-around whendisabled => $stz;
-
=head2 confirm
$alert->confirm();
diff --git a/perllib/FixMyStreet/DB/Result/AlertSent.pm b/perllib/FixMyStreet/DB/Result/AlertSent.pm
index 83043a33b..d4e669f7f 100644
--- a/perllib/FixMyStreet/DB/Result/AlertSent.pm
+++ b/perllib/FixMyStreet/DB/Result/AlertSent.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("alert_sent");
__PACKAGE__->add_columns(
"alert_id",
@@ -31,8 +35,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2015-08-13 16:33:38
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/+Vodu8VJxJ0EY9P3Qjjjw
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:xriosaSCkOo/REOG1OxdQA
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/AlertType.pm b/perllib/FixMyStreet/DB/Result/AlertType.pm
index 3aa9677e0..3d9603008 100644
--- a/perllib/FixMyStreet/DB/Result/AlertType.pm
+++ b/perllib/FixMyStreet/DB/Result/AlertType.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("alert_type");
__PACKAGE__->add_columns(
"ref",
@@ -47,8 +51,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-03-08 17:19:55
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:KDBYzNEAM5lPvZjb9cv22g
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:7JyCGS/rEvL1++p520749w
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/Body.pm b/perllib/FixMyStreet/DB/Result/Body.pm
index 74a38f225..663181746 100644
--- a/perllib/FixMyStreet/DB/Result/Body.pm
+++ b/perllib/FixMyStreet/DB/Result/Body.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("body");
__PACKAGE__->add_columns(
"id",
@@ -18,6 +22,12 @@ __PACKAGE__->add_columns(
is_nullable => 0,
sequence => "body_id_seq",
},
+ "name",
+ { data_type => "text", is_nullable => 0 },
+ "external_url",
+ { data_type => "text", is_nullable => 1 },
+ "parent",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
"endpoint",
{ data_type => "text", is_nullable => 1 },
"jurisdiction",
@@ -36,20 +46,14 @@ __PACKAGE__->add_columns(
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
"send_extended_statuses",
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
- "name",
- { data_type => "text", is_nullable => 0 },
- "parent",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
- "deleted",
- { data_type => "boolean", default_value => \"false", is_nullable => 0 },
- "external_url",
- { data_type => "text", is_nullable => 1 },
"fetch_problems",
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
"blank_updates_permitted",
- { data_type => "boolean", default_value => \"false", is_nullable => 1 },
+ { data_type => "boolean", default_value => \"false", is_nullable => 0 },
"convert_latlong",
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
+ "deleted",
+ { data_type => "boolean", default_value => \"false", is_nullable => 0 },
"extra",
{ data_type => "text", is_nullable => 1 },
);
@@ -126,22 +130,30 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2018-04-05 14:29:33
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:HV8IM2C1ErrpvXoRTZ1B1Q
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:8CuxbffDaYS7TFlgff1nEg
__PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn");
__PACKAGE__->rabx_column('extra');
use Moo;
use namespace::clean;
+use FixMyStreet::MapIt;
with 'FixMyStreet::Roles::Translatable',
'FixMyStreet::Roles::Extra';
+sub _url {
+ my ( $obj, $cobrand, $args ) = @_;
+ my $uri = URI->new('/reports/' . $cobrand->short_name($obj));
+ $uri->query_form($args) if $args;
+ return $uri;
+}
+
sub url {
my ( $self, $c, $args ) = @_;
- # XXX $areas_info was used here for Norway parent - needs body parents, I guess
- return $c->uri_for( '/reports/' . $c->cobrand->short_name( $self ), $args || {} );
+ my $cobrand = $self->result_source->schema->cobrand;
+ return _url($self, $cobrand, $args);
}
__PACKAGE__->might_have(
@@ -174,7 +186,8 @@ sub first_area_children {
return unless $body_area;
my $cobrand = $self->result_source->schema->cobrand;
- my $children = mySociety::MaPit::call('area/children', $body_area->area_id,
+
+ my $children = FixMyStreet::MapIt::call('area/children', $body_area->area_id,
type => $cobrand->area_types_children,
);
@@ -197,7 +210,8 @@ sub get_cobrand_handler {
}
sub calculate_average {
- my ($self) = @_;
+ my ($self, $threshold) = @_;
+ $threshold ||= 0;
my $substmt = "select min(id) from comment where me.problem_id=comment.problem_id and (problem_state in ('fixed', 'fixed - council', 'fixed - user') or mark_fixed)";
my $subquery = FixMyStreet::DB->resultset('Comment')->to_body($self)->search({
@@ -207,6 +221,7 @@ sub calculate_average {
],
'me.id' => \"= ($substmt)",
'me.state' => 'confirmed',
+ 'problem.state' => [ FixMyStreet::DB::Result::Problem->visible_states() ],
}, {
select => [
{ extract => "epoch from me.confirmed-problem.confirmed", -as => 'time' },
@@ -217,12 +232,15 @@ sub calculate_average {
join => 'problem'
})->as_subselect_rs;
- my $avg = $subquery->search({
+ my $result = $subquery->search({
}, {
- select => [ { avg => "time" } ],
- as => [ qw/avg/ ],
- })->first->get_column('avg');
- return $avg;
+ select => [ { avg => "time" }, { count => "time" } ],
+ as => [ qw/avg count/ ],
+ })->first;
+ my $avg = $result->get_column('avg');
+ my $count = $result->get_column('count');
+
+ return $count >= $threshold ? $avg : undef;
}
1;
diff --git a/perllib/FixMyStreet/DB/Result/BodyArea.pm b/perllib/FixMyStreet/DB/Result/BodyArea.pm
index 4447777dc..7f0956c7d 100644
--- a/perllib/FixMyStreet/DB/Result/BodyArea.pm
+++ b/perllib/FixMyStreet/DB/Result/BodyArea.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("body_areas");
__PACKAGE__->add_columns(
"body_id",
@@ -25,8 +29,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2013-09-10 17:11:54
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:+hzie6kHleUBoEt199c/nQ
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:VPs3e9McGNO+Dd7C4pApxw
__PACKAGE__->set_primary_key(__PACKAGE__->columns);
diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm
index 8a4dbe475..5d0253ef4 100644
--- a/perllib/FixMyStreet/DB/Result/Comment.pm
+++ b/perllib/FixMyStreet/DB/Result/Comment.pm
@@ -6,10 +6,13 @@ package FixMyStreet::DB::Result::Comment;
use strict;
use warnings;
-use FixMyStreet::Template;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("comment");
__PACKAGE__->add_columns(
"id",
@@ -70,8 +73,8 @@ __PACKAGE__->add_columns(
{ data_type => "timestamp", is_nullable => 1 },
);
__PACKAGE__->set_primary_key("id");
-__PACKAGE__->might_have(
- "moderation_original_data",
+__PACKAGE__->has_many(
+ "moderation_original_datas",
"FixMyStreet::DB::Result::ModerationOriginalData",
{ "foreign.comment_id" => "self.id" },
{ cascade_copy => 0, cascade_delete => 0 },
@@ -90,8 +93,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2015-08-13 16:33:38
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZR+YNA1Jej3s+8mr52iq6Q
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:CozqNY621I8G7kUPXi5RoQ
#
__PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn");
@@ -99,21 +102,32 @@ __PACKAGE__->rabx_column('extra');
use Moo;
use namespace::clean -except => [ 'meta' ];
+use FixMyStreet::Template;
with 'FixMyStreet::Roles::Abuser',
'FixMyStreet::Roles::Extra',
+ 'FixMyStreet::Roles::Moderation',
'FixMyStreet::Roles::PhotoSet';
-my $stz = sub {
- my ( $orig, $self ) = ( shift, shift );
- my $s = $self->$orig(@_);
- return $s unless $s && UNIVERSAL::isa($s, "DateTime");
- FixMyStreet->set_time_zone($s);
- return $s;
-};
+=head2 get_cobrand_logged
+
+Get a cobrand object for the cobrand the update was made on.
+
+e.g. if an update was logged at www.fixmystreet.com, this will be a
+FixMyStreet::Cobrand::FixMyStreet object.
+
+=cut
+
+has get_cobrand_logged => (
+ is => 'ro',
+ lazy => 1,
+ default => sub {
+ my $self = shift;
+ my $cobrand_class = FixMyStreet::Cobrand->get_class_for_moniker( $self->cobrand );
+ return $cobrand_class->new;
+ },
+);
-around created => $stz;
-around confirmed => $stz;
# You can replace this text with custom code or comments, and it will be preserved on regeneration
@@ -156,17 +170,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",
@@ -177,24 +180,24 @@ __PACKAGE__->has_many(
}
);
-# we already had the `moderation_original_data` rel above, as inferred by
-# Schema::Loader, but that doesn't know about the problem_id mapping, so we now
-# (slightly hackishly) redefine here:
-#
-# we also add cascade_delete, though this seems to be insufficient.
-#
-# TODO: should add FK on moderation_original_data field for this, to get S::L to
-# pick up without hacks.
-
+# This will return the oldest moderation_original_data, if any.
+# The plural can be used to return all entries.
__PACKAGE__->might_have(
"moderation_original_data",
"FixMyStreet::DB::Result::ModerationOriginalData",
{ "foreign.comment_id" => "self.id",
"foreign.problem_id" => "self.problem_id",
},
- { cascade_copy => 0, cascade_delete => 1 },
+ { order_by => 'id',
+ rows => 1,
+ 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
@@ -228,7 +231,9 @@ sub meta_line {
$body = "$body <img src='/cobrands/greenwich/favicon.png' alt=''>";
}
}
- my $can_view_contribute = $c->user_exists && $c->user->has_permission_to('view_body_contribute_details', $self->problem->bodies_str_ids);
+ my $cobrand_always_view_body_user = $c->cobrand->call_hook("always_view_body_contribute_details");
+ my $can_view_contribute = $cobrand_always_view_body_user ||
+ ($c->user_exists && $c->user->has_permission_to('view_body_contribute_details', $self->problem->bodies_str_ids));
if ($self->text) {
if ($can_view_contribute) {
$meta = sprintf( _( 'Posted by <strong>%s</strong> (%s) at %s' ), $body, $user_name, Utils::prettify_dt( $self->confirmed ) );
@@ -253,24 +258,22 @@ sub meta_line {
return $meta;
};
+sub problem_state_processed {
+ my $self = shift;
+ return 'fixed - user' if $self->mark_fixed;
+ return 'confirmed' if $self->mark_open;
+ return $self->problem_state;
+}
+
sub problem_state_display {
my ( $self, $c ) = @_;
- my $update_state = '';
- my $cobrand = $c->cobrand->moniker;
-
- if ($self->mark_fixed) {
- return FixMyStreet::DB->resultset("State")->display('fixed', 1);
- } elsif ($self->mark_open) {
- return FixMyStreet::DB->resultset("State")->display('confirmed', 1);
- } elsif ($self->problem_state) {
- my $state = $self->problem_state;
- my $cobrand_name = $cobrand;
- $cobrand_name = 'bromley' if $self->problem->to_body_named('Bromley');
- $update_state = FixMyStreet::DB->resultset("State")->display($state, 1, $cobrand_name);
- }
+ my $state = $self->problem_state_processed;
+ return '' unless $state;
- return $update_state;
+ my $cobrand_name = $c->cobrand->moniker;
+ $cobrand_name = 'bromley' if $self->problem->to_body_named('Bromley');
+ return FixMyStreet::DB->resultset("State")->display($state, 1, $cobrand_name);
}
sub is_latest {
@@ -298,4 +301,27 @@ sub hide {
return $ret;
}
+sub as_hashref {
+ my ($self, $c, $cols) = @_;
+
+ my $out = {
+ id => $self->id,
+ problem_id => $self->problem_id,
+ text => $self->text,
+ state => $self->state,
+ created => $self->created,
+ };
+
+ $out->{problem_state} = $self->problem_state_processed;
+
+ $out->{photos} = [ map { $_->{url} } @{$self->photos} ] if !$cols || $cols->{photos};
+
+ if ($self->confirmed) {
+ $out->{confirmed} = $self->confirmed if !$cols || $cols->{confirmed};
+ $out->{confirmed_pp} = $c->cobrand->prettify_dt( $self->confirmed ) if !$cols || $cols->{confirmed_pp};
+ }
+
+ return $out;
+}
+
1;
diff --git a/perllib/FixMyStreet/DB/Result/Contact.pm b/perllib/FixMyStreet/DB/Result/Contact.pm
index c544f084a..17620f279 100644
--- a/perllib/FixMyStreet/DB/Result/Contact.pm
+++ b/perllib/FixMyStreet/DB/Result/Contact.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("contacts");
__PACKAGE__->add_columns(
"id",
@@ -24,6 +28,8 @@ __PACKAGE__->add_columns(
{ data_type => "text", default_value => "Other", is_nullable => 0 },
"email",
{ data_type => "text", is_nullable => 0 },
+ "state",
+ { data_type => "text", is_nullable => 0 },
"editor",
{ data_type => "text", is_nullable => 0 },
"whenedited",
@@ -42,8 +48,6 @@ __PACKAGE__->add_columns(
{ data_type => "text", default_value => "", is_nullable => 1 },
"send_method",
{ data_type => "text", is_nullable => 1 },
- "state",
- { data_type => "text", is_nullable => 0 },
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->add_unique_constraint("contacts_body_id_category_idx", ["body_id", "category"]);
@@ -73,8 +77,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-07-08 20:45:04
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:t/VtPP11R8bbqPZdEVXffw
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:f7XjQj4iABikbR4EZrjL3g
__PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn");
__PACKAGE__->rabx_column('extra');
@@ -94,14 +98,9 @@ sub category_display {
$self->translate_column('category');
}
-sub get_metadata_for_input {
+sub get_metadata_for_editing {
my $self = shift;
- my $id_field = $self->id_field;
my @metadata = @{$self->get_extra_fields};
- # First, ones we always want to ignore (hard-coded, old system)
- @metadata = grep { $_->{code} !~ /^(easting|northing|closest_address|$id_field)$/ } @metadata;
- # Also ignore any we have with a 'server_set' automated attribute
- @metadata = grep { !$_->{automated} || $_->{automated} ne 'server_set' } @metadata;
# Just in case the extra data is in an old parsed format
foreach (@metadata) {
@@ -112,6 +111,16 @@ sub get_metadata_for_input {
return \@metadata;
}
+sub get_metadata_for_input {
+ my $self = shift;
+ my $metadata = $self->get_metadata_for_editing;
+
+ # Also ignore any we have with a 'server_set' automated attribute
+ my @metadata = grep { !$_->{automated} || $_->{automated} ne 'server_set' } @$metadata;
+
+ return \@metadata;
+}
+
sub id_field {
my $self = shift;
return $self->get_extra_metadata('id_field') || 'fixmystreet_id';
diff --git a/perllib/FixMyStreet/DB/Result/ContactDefectType.pm b/perllib/FixMyStreet/DB/Result/ContactDefectType.pm
index 2199f0b42..25d842e23 100644
--- a/perllib/FixMyStreet/DB/Result/ContactDefectType.pm
+++ b/perllib/FixMyStreet/DB/Result/ContactDefectType.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("contact_defect_types");
__PACKAGE__->add_columns(
"id",
@@ -38,8 +42,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-02-13 15:11:11
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:VIczmM0OXXpWgQVpop3SMw
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:yjQ/+17jn8fW8J70fFtvgg
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/ContactResponsePriority.pm b/perllib/FixMyStreet/DB/Result/ContactResponsePriority.pm
index d5afd75a7..8406e2762 100644
--- a/perllib/FixMyStreet/DB/Result/ContactResponsePriority.pm
+++ b/perllib/FixMyStreet/DB/Result/ContactResponsePriority.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("contact_response_priorities");
__PACKAGE__->add_columns(
"id",
@@ -38,8 +42,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2016-09-06 15:33:04
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:kM/9jY1QSgakyPTvutS+hw
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:NvXWYJu14GUXEHztl3Zp4w
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/ContactResponseTemplate.pm b/perllib/FixMyStreet/DB/Result/ContactResponseTemplate.pm
index 3c777533c..3139b2c84 100644
--- a/perllib/FixMyStreet/DB/Result/ContactResponseTemplate.pm
+++ b/perllib/FixMyStreet/DB/Result/ContactResponseTemplate.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("contact_response_templates");
__PACKAGE__->add_columns(
"id",
@@ -38,8 +42,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2016-08-24 11:29:04
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:d6niNsxi2AsijhvJSuQeKw
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:PE5+8AZp77pb+tDFEwiOqg
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/ContactsHistory.pm b/perllib/FixMyStreet/DB/Result/ContactsHistory.pm
index c90bb9d66..5a6039d6a 100644
--- a/perllib/FixMyStreet/DB/Result/ContactsHistory.pm
+++ b/perllib/FixMyStreet/DB/Result/ContactsHistory.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("contacts_history");
__PACKAGE__->add_columns(
"contacts_history_id",
@@ -26,20 +30,20 @@ __PACKAGE__->add_columns(
{ data_type => "text", default_value => "Other", is_nullable => 0 },
"email",
{ data_type => "text", is_nullable => 0 },
+ "state",
+ { data_type => "text", is_nullable => 0 },
"editor",
{ data_type => "text", is_nullable => 0 },
"whenedited",
{ data_type => "timestamp", is_nullable => 0 },
"note",
{ data_type => "text", is_nullable => 0 },
- "state",
- { data_type => "text", is_nullable => 0 },
);
__PACKAGE__->set_primary_key("contacts_history_id");
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-07-08 20:45:04
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:HTt0g29yXTM/WyHKN179FA
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:es6F6L3MS8pEUDprFplnYg
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/DefectType.pm b/perllib/FixMyStreet/DB/Result/DefectType.pm
index a2969f59e..baee066af 100644
--- a/perllib/FixMyStreet/DB/Result/DefectType.pm
+++ b/perllib/FixMyStreet/DB/Result/DefectType.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("defect_types");
__PACKAGE__->add_columns(
"id",
@@ -49,8 +53,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-02-13 15:11:11
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BBLjb/aAoTKJZerdYCeBMQ
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:d5Gkeysiz/1P/Ww4Xur0vA
__PACKAGE__->many_to_many( contacts => 'contact_defect_types', 'contact' );
diff --git a/perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm b/perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm
index d7240cd5d..18d2a7683 100644
--- a/perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm
+++ b/perllib/FixMyStreet/DB/Result/ModerationOriginalData.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("moderation_original_data");
__PACKAGE__->add_columns(
"id",
@@ -37,9 +41,16 @@ __PACKAGE__->add_columns(
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__->add_unique_constraint("moderation_original_data_comment_id_key", ["comment_id"]);
__PACKAGE__->belongs_to(
"comment",
"FixMyStreet::DB::Result::Comment",
@@ -59,9 +70,149 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2015-08-13 16:33:38
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:DBtGjCJykDtLnGtkj638eA
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:FLKiZELcfBcc9VwHU2MZYQ
+
+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 {
+ "<del style='background-color:#fcc'>$_</del>";
+ } @deleted) . (join ', ', map {
+ "<ins style='background-color:#cfc'>$_</ins>";
+ } @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 .= "<del style='background-color:#fcc'>$deleted</del>";
+ }
+ my $inserted = join '', $diff->Items(2);
+ if ($d & 2) {
+ $string .= "<ins style='background-color:#cfc'>$inserted</ins>";
+ } else {
+ $string .= $inserted;
+ }
+ }
+ return $string;
+}
-# You can replace this text with custom code or comments, and it will be preserved on regeneration
1;
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm
index f67e0b0f8..dc45091ee 100644
--- a/perllib/FixMyStreet/DB/Result/Problem.pm
+++ b/perllib/FixMyStreet/DB/Result/Problem.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("problem");
__PACKAGE__->add_columns(
"id",
@@ -20,14 +24,38 @@ __PACKAGE__->add_columns(
},
"postcode",
{ data_type => "text", is_nullable => 0 },
+ "latitude",
+ { data_type => "double precision", is_nullable => 0 },
+ "longitude",
+ { data_type => "double precision", is_nullable => 0 },
+ "bodies_str",
+ { data_type => "text", is_nullable => 1 },
+ "bodies_missing",
+ { data_type => "text", is_nullable => 1 },
+ "areas",
+ { data_type => "text", is_nullable => 0 },
+ "category",
+ { data_type => "text", default_value => "Other", is_nullable => 0 },
"title",
{ data_type => "text", is_nullable => 0 },
"detail",
{ data_type => "text", is_nullable => 0 },
"photo",
{ data_type => "bytea", is_nullable => 1 },
+ "used_map",
+ { data_type => "boolean", is_nullable => 0 },
+ "user_id",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"name",
{ data_type => "text", is_nullable => 0 },
+ "anonymous",
+ { data_type => "boolean", is_nullable => 0 },
+ "external_id",
+ { data_type => "text", is_nullable => 1 },
+ "external_body",
+ { data_type => "text", is_nullable => 1 },
+ "external_team",
+ { data_type => "text", is_nullable => 1 },
"created",
{
data_type => "timestamp",
@@ -35,57 +63,37 @@ __PACKAGE__->add_columns(
is_nullable => 0,
original => { default_value => \"now()" },
},
- "state",
- { data_type => "text", is_nullable => 0 },
- "whensent",
- { data_type => "timestamp", is_nullable => 1 },
- "used_map",
- { data_type => "boolean", is_nullable => 0 },
- "bodies_str",
- { data_type => "text", is_nullable => 1 },
- "anonymous",
- { data_type => "boolean", is_nullable => 0 },
- "category",
- { data_type => "text", default_value => "Other", is_nullable => 0 },
"confirmed",
{ data_type => "timestamp", is_nullable => 1 },
- "send_questionnaire",
- { data_type => "boolean", default_value => \"true", is_nullable => 0 },
- "lastupdate",
- {
- data_type => "timestamp",
- default_value => \"current_timestamp",
- is_nullable => 0,
- original => { default_value => \"now()" },
- },
- "areas",
+ "state",
{ data_type => "text", is_nullable => 0 },
- "service",
- { data_type => "text", default_value => "", is_nullable => 0 },
"lang",
{ data_type => "text", default_value => "en-gb", is_nullable => 0 },
+ "service",
+ { data_type => "text", default_value => "", is_nullable => 0 },
"cobrand",
{ data_type => "text", default_value => "", is_nullable => 0 },
"cobrand_data",
{ data_type => "text", default_value => "", is_nullable => 0 },
- "latitude",
- { data_type => "double precision", is_nullable => 0 },
- "longitude",
- { data_type => "double precision", is_nullable => 0 },
- "external_id",
- { data_type => "text", is_nullable => 1 },
- "external_body",
- { data_type => "text", is_nullable => 1 },
- "external_team",
+ "lastupdate",
+ {
+ data_type => "timestamp",
+ default_value => \"current_timestamp",
+ is_nullable => 0,
+ original => { default_value => \"now()" },
+ },
+ "whensent",
+ { data_type => "timestamp", is_nullable => 1 },
+ "send_questionnaire",
+ { data_type => "boolean", default_value => \"true", is_nullable => 0 },
+ "extra",
{ data_type => "text", is_nullable => 1 },
- "user_id",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"flagged",
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
- "extra",
- { data_type => "text", is_nullable => 1 },
"geocode",
{ data_type => "bytea", is_nullable => 1 },
+ "response_priority_id",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
"send_fail_count",
{ data_type => "integer", default_value => 0, is_nullable => 0 },
"send_fail_reason",
@@ -104,10 +112,6 @@ __PACKAGE__->add_columns(
{ data_type => "integer", default_value => 0, is_nullable => 1 },
"subcategory",
{ data_type => "text", is_nullable => 1 },
- "bodies_missing",
- { data_type => "text", is_nullable => 1 },
- "response_priority_id",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
"defect_type_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
);
@@ -166,8 +170,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-02-13 15:11:11
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:8zzWlJX7OQOdvrGxKuZUmg
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hUXle+TtlkDkxkBrVa/u+g
# Add fake relationship to stored procedure table
__PACKAGE__->has_one(
@@ -177,11 +181,15 @@ __PACKAGE__->has_one(
{ cascade_copy => 0, cascade_delete => 0 },
);
+# This will return the oldest moderation_original_data, if any.
+# The plural can be used to return all entries.
__PACKAGE__->might_have(
"moderation_original_data",
"FixMyStreet::DB::Result::ModerationOriginalData",
{ "foreign.problem_id" => "self.id" },
{ where => { 'comment_id' => undef },
+ order_by => 'id',
+ rows => 1,
cascade_copy => 0, cascade_delete => 1 },
);
@@ -206,6 +214,7 @@ my $IM = eval {
with 'FixMyStreet::Roles::Abuser',
'FixMyStreet::Roles::Extra',
+ 'FixMyStreet::Roles::Moderation',
'FixMyStreet::Roles::Translatable',
'FixMyStreet::Roles::PhotoSet';
@@ -318,19 +327,6 @@ sub visible_states_remove {
}
}
-my $stz = sub {
- my ( $orig, $self ) = ( shift, shift );
- my $s = $self->$orig(@_);
- return $s unless $s && UNIVERSAL::isa($s, "DateTime");
- FixMyStreet->set_time_zone($s);
- return $s;
-};
-
-around created => $stz;
-around confirmed => $stz;
-around whensent => $stz;
-around lastupdate => $stz;
-
around service => sub {
my ( $orig, $self ) = ( shift, shift );
# service might be undef if e.g. unsaved code report
@@ -663,7 +659,7 @@ sub body {
my @body_names = sort map {
my $name = $_->name;
if ($c and FixMyStreet->config('AREA_LINKS_FROM_PROBLEMS')) {
- '<a href="' . $_->url($c) . '">' . $name . '</a>';
+ '<a href="' . $_->url . '">' . $name . '</a>';
} else {
$name;
}
@@ -759,7 +755,7 @@ sub defect_types {
# Note: this only makes sense when called on a problem that has been sent!
sub can_display_external_id {
my $self = shift;
- if ($self->external_id && $self->send_method_used && $self->to_body_named('Oxfordshire|Angus')) {
+ if ($self->external_id && $self->send_method_used && $self->to_body_named('Oxfordshire|Lincolnshire')) {
return 1;
}
return 0;
@@ -780,7 +776,7 @@ sub duration_string {
sub local_coords {
my $self = shift;
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($self->cobrand)->new;
+ my $cobrand = $self->get_cobrand_logged;
if ($cobrand->moniker eq 'zurich') {
my ($x, $y) = Geo::Coordinates::CH1903Plus::from_latlon($self->latitude, $self->longitude);
return ( int($x+0.5), int($y+0.5) );
@@ -893,11 +889,12 @@ bodies by some mechanism. Right now that mechanism is Open311.
sub updates_sent_to_body {
my $self = shift;
- return unless $self->send_method_used && $self->send_method_used eq 'Open311';
+ return unless $self->send_method_used && $self->send_method_used =~ /Open311/;
# Some bodies only send updates *to* FMS, they don't receive updates.
- # NB See also the list in bin/send-comments
- my $excluded = qr{Lewisham|Oxfordshire};
+ my $cobrand = $self->get_cobrand_logged;
+ my $handler = $cobrand->call_hook(get_body_handler_for_problem => $self);
+ return 0 if $handler && $handler->call_hook('open311_post_update_skip');
my @bodies = values %{ $self->bodies };
my @updates_sent = grep {
@@ -905,8 +902,7 @@ sub updates_sent_to_body {
(
$_->send_method eq 'Open311' ||
$_->send_method eq 'Noop' # Sending might be temporarily disabled
- ) &&
- !($_->name =~ /$excluded/)
+ )
} @bodies;
return scalar @updates_sent;
}
@@ -922,6 +918,12 @@ sub add_send_method {
}
}
+sub resend {
+ my $self = shift;
+ $self->whensent(undef);
+ $self->send_method_used(undef);
+}
+
sub as_hashref {
my ($self, $c, $cols) = @_;
@@ -952,17 +954,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;
-}
-
__PACKAGE__->has_many(
"admin_log_entries",
"FixMyStreet::DB::Result::AdminLog",
@@ -973,6 +964,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({},
@@ -1017,6 +1013,7 @@ sub pin_data {
id => $self->id,
title => $title,
problem => $self,
+ draggable => $opts{draggable},
type => $opts{type},
}
};
diff --git a/perllib/FixMyStreet/DB/Result/Questionnaire.pm b/perllib/FixMyStreet/DB/Result/Questionnaire.pm
index 30f2ab7ce..2d5445669 100644
--- a/perllib/FixMyStreet/DB/Result/Questionnaire.pm
+++ b/perllib/FixMyStreet/DB/Result/Questionnaire.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("questionnaire");
__PACKAGE__->add_columns(
"id",
@@ -40,21 +44,17 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2013-09-10 17:11:54
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:oL1Hk4/bNG14CY74GA75SA
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:AWRb6itjsVkG5VUDRmBTIg
use Moo;
use namespace::clean -except => [ 'meta' ];
-my $stz = sub {
- my ( $orig, $self ) = ( shift, shift );
- my $s = $self->$orig(@_);
- return $s unless $s && UNIVERSAL::isa($s, "DateTime");
- FixMyStreet->set_time_zone($s);
- return $s;
-};
-
-around whensent => $stz;
-around whenanswered => $stz;
+sub marks_fixed {
+ my $self = shift;
+ my $new_fixed = FixMyStreet::DB::Result::Problem->fixed_states()->{$self->new_state};
+ my $old_fixed = FixMyStreet::DB::Result::Problem->fixed_states()->{$self->old_state};
+ return $new_fixed && !$old_fixed;
+}
1;
diff --git a/perllib/FixMyStreet/DB/Result/ReportExtraFields.pm b/perllib/FixMyStreet/DB/Result/ReportExtraField.pm
index 27a6bd2c6..f88169bba 100644
--- a/perllib/FixMyStreet/DB/Result/ReportExtraFields.pm
+++ b/perllib/FixMyStreet/DB/Result/ReportExtraField.pm
@@ -1,5 +1,5 @@
use utf8;
-package FixMyStreet::DB::Result::ReportExtraFields;
+package FixMyStreet::DB::Result::ReportExtraField;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("report_extra_fields");
__PACKAGE__->add_columns(
"id",
@@ -30,8 +34,8 @@ __PACKAGE__->add_columns(
__PACKAGE__->set_primary_key("id");
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-07-28 09:51:34
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:LkfbsUInnEyXowdcCEPjUQ
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 15:41:27
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:yRF676ybdkfalMwZ9V+yhw
__PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn");
__PACKAGE__->rabx_column('extra');
diff --git a/perllib/FixMyStreet/DB/Result/ResponsePriority.pm b/perllib/FixMyStreet/DB/Result/ResponsePriority.pm
index df54cfa08..a478ac7b9 100644
--- a/perllib/FixMyStreet/DB/Result/ResponsePriority.pm
+++ b/perllib/FixMyStreet/DB/Result/ResponsePriority.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("response_priorities");
__PACKAGE__->add_columns(
"id",
@@ -20,10 +24,10 @@ __PACKAGE__->add_columns(
},
"body_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
- "name",
- { data_type => "text", is_nullable => 0 },
"deleted",
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
+ "name",
+ { data_type => "text", is_nullable => 0 },
"description",
{ data_type => "text", is_nullable => 1 },
"external_id",
@@ -53,8 +57,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-09-12 09:32:53
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:JBIHFnaLvXCAUjgwTSB3CQ
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:gIttzSJcQ8GxTowrQZ8oAw
__PACKAGE__->many_to_many( contacts => 'contact_response_priorities', 'contact' );
diff --git a/perllib/FixMyStreet/DB/Result/ResponseTemplate.pm b/perllib/FixMyStreet/DB/Result/ResponseTemplate.pm
index 73e0d898e..85bf80aef 100644
--- a/perllib/FixMyStreet/DB/Result/ResponseTemplate.pm
+++ b/perllib/FixMyStreet/DB/Result/ResponseTemplate.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("response_templates");
__PACKAGE__->add_columns(
"id",
@@ -54,8 +58,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07048 @ 2018-03-22 11:18:36
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:p0+/jFma6H9eZ3MZAJQRaQ
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:MzTa7p2rryKkxbRi7zN+Uw
__PACKAGE__->many_to_many( contacts => 'contact_response_templates', 'contact' );
diff --git a/perllib/FixMyStreet/DB/Result/Secret.pm b/perllib/FixMyStreet/DB/Result/Secret.pm
index 449dfec0e..045375fef 100644
--- a/perllib/FixMyStreet/DB/Result/Secret.pm
+++ b/perllib/FixMyStreet/DB/Result/Secret.pm
@@ -8,13 +8,17 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("secret");
__PACKAGE__->add_columns("secret", { data_type => "text", is_nullable => 0 });
-# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-03-08 17:19:55
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:9XiWSKJ1PD3LSYjrSA3drw
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:mVU/XGxS3DVhEcHTA2srgA
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/Session.pm b/perllib/FixMyStreet/DB/Result/Session.pm
index a478c5444..94f7e823c 100644
--- a/perllib/FixMyStreet/DB/Result/Session.pm
+++ b/perllib/FixMyStreet/DB/Result/Session.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("sessions");
__PACKAGE__->add_columns(
"id",
@@ -21,8 +25,8 @@ __PACKAGE__->add_columns(
__PACKAGE__->set_primary_key("id");
-# Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-03-08 17:19:55
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:MVmCn4gLQWXTDIIaDHiVmA
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:HoYrCwULpxJVJ1m9ASMk3A
use Storable;
use MIME::Base64;
diff --git a/perllib/FixMyStreet/DB/Result/State.pm b/perllib/FixMyStreet/DB/Result/State.pm
index b8a35d42b..66477111b 100644
--- a/perllib/FixMyStreet/DB/Result/State.pm
+++ b/perllib/FixMyStreet/DB/Result/State.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("state");
__PACKAGE__->add_columns(
"id",
@@ -30,8 +34,8 @@ __PACKAGE__->add_unique_constraint("state_label_key", ["label"]);
__PACKAGE__->add_unique_constraint("state_name_key", ["name"]);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-08-22 15:17:43
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:dvtAOpeYqEF9T3otHHgLqw
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:f/QeR3FYL/4wIGRu3c/C/A
use Moo;
use namespace::clean;
diff --git a/perllib/FixMyStreet/DB/Result/Token.pm b/perllib/FixMyStreet/DB/Result/Token.pm
index a60e23839..444d5e5a8 100644
--- a/perllib/FixMyStreet/DB/Result/Token.pm
+++ b/perllib/FixMyStreet/DB/Result/Token.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("token");
__PACKAGE__->add_columns(
"scope",
@@ -28,8 +32,8 @@ __PACKAGE__->add_columns(
__PACKAGE__->set_primary_key("scope", "token");
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2015-08-13 16:33:38
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:HkvzOY5STjOdXN64hxg5NA
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:km/1K3PurX8bbgnYPWgLIA
use mySociety::AuthToken;
diff --git a/perllib/FixMyStreet/DB/Result/Translation.pm b/perllib/FixMyStreet/DB/Result/Translation.pm
index fafc7ccf1..4d6373d40 100644
--- a/perllib/FixMyStreet/DB/Result/Translation.pm
+++ b/perllib/FixMyStreet/DB/Result/Translation.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("translation");
__PACKAGE__->add_columns(
"id",
@@ -36,8 +40,8 @@ __PACKAGE__->add_unique_constraint(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-07-14 23:24:32
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:///VNqg4BOuO29xKhnY8vw
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:EsseG51ZpQa5QYHPCpkL8A
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm
index 8b539f85d..d01ba92d0 100644
--- a/perllib/FixMyStreet/DB/Result/User.pm
+++ b/perllib/FixMyStreet/DB/Result/User.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("users");
__PACKAGE__->add_columns(
"id",
@@ -36,16 +40,6 @@ __PACKAGE__->add_columns(
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
"is_superuser",
{ data_type => "boolean", default_value => \"false", is_nullable => 0 },
- "title",
- { data_type => "text", is_nullable => 1 },
- "twitter_id",
- { data_type => "bigint", is_nullable => 1 },
- "facebook_id",
- { data_type => "bigint", is_nullable => 1 },
- "area_id",
- { data_type => "integer", is_nullable => 1 },
- "extra",
- { data_type => "text", is_nullable => 1 },
"created",
{
data_type => "timestamp",
@@ -60,6 +54,16 @@ __PACKAGE__->add_columns(
is_nullable => 0,
original => { default_value => \"now()" },
},
+ "title",
+ { data_type => "text", is_nullable => 1 },
+ "twitter_id",
+ { data_type => "bigint", is_nullable => 1 },
+ "facebook_id",
+ { data_type => "bigint", is_nullable => 1 },
+ "extra",
+ { data_type => "text", is_nullable => 1 },
+ "area_ids",
+ { data_type => "integer[]", is_nullable => 1 },
);
__PACKAGE__->set_primary_key("id");
__PACKAGE__->add_unique_constraint("users_facebook_id_key", ["facebook_id"]);
@@ -119,8 +123,8 @@ __PACKAGE__->has_many(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2018-05-23 18:54:36
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/V7+Ygv/t6VX8dDhNGN16w
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:BCCqv3JCec8psuRk/SdCJQ
# These are not fully unique constraints (they only are when the *_verified
# is true), but this is managed in ResultSet::User's find() wrapper.
@@ -131,6 +135,7 @@ __PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn");
__PACKAGE__->rabx_column('extra');
use Moo;
+use Text::CSV;
use FixMyStreet::SMS;
use mySociety::EmailUtil;
use namespace::clean -except => [ 'meta' ];
@@ -175,8 +180,8 @@ sub phone_display {
sub latest_anonymity {
my $self = shift;
- my $p = $self->problems->search(undef, { order_by => { -desc => 'id' } } )->first;
- my $c = $self->comments->search(undef, { order_by => { -desc => 'id' } } )->first;
+ my $p = $self->problems->search(undef, { rows => 1, order_by => { -desc => 'id' } } )->first;
+ my $c = $self->comments->search(undef, { rows => 1, order_by => { -desc => 'id' } } )->first;
my $p_created = $p ? $p->created->epoch : 0;
my $c_created = $c ? $c->created->epoch : 0;
my $obj = $p_created >= $c_created ? $p : $c;
@@ -291,6 +296,11 @@ sub body {
return $self->from_body->name;
}
+sub moderating_user_name {
+ my $self = shift;
+ return $self->body || _('an administrator');
+}
+
=head2 belongs_to_body
$belongs_to_body = $user->belongs_to_body( $bodies );
@@ -329,6 +339,37 @@ sub split_name {
return { first => $first || '', last => $last || '' };
}
+sub can_moderate {
+ my ($self, $object, $perms) = @_;
+
+ my ($type, $ids);
+ if ($object->isa("FixMyStreet::DB::Result::Comment")) {
+ $type = 'update';
+ $ids = $object->problem->bodies_str_ids;
+ } else {
+ $type = 'problem';
+ $ids = $object->bodies_str_ids;
+ }
+
+ my $staff_perm = exists($perms->{staff}) ? $perms->{staff} : $self->has_permission_to(moderate => $ids);
+ return 1 if $staff_perm;
+
+ # See if the cobrand wants to allow it in some circumstance
+ my $cobrand = $self->result_source->schema->cobrand;
+ return $cobrand->call_hook('moderate_permission', $self, $type => $object);
+}
+
+sub can_moderate_title {
+ my ($self, $problem, $perm) = @_;
+
+ # Must have main permission, this is to potentially restrict only
+ return 0 unless $perm;
+
+ # If hook returns anything use it, otherwise default to yes
+ my $cobrand = $self->result_source->schema->cobrand;
+ return $cobrand->call_hook('moderate_permission_title', $self, $problem) // 1;
+}
+
has body_permissions => (
is => 'ro',
lazy => 1,
@@ -339,13 +380,16 @@ has body_permissions => (
);
sub permissions {
- my ($self, $c, $body_id) = @_;
+ my ($self, $problem) = @_;
+ my $cobrand = $self->result_source->schema->cobrand;
if ($self->is_superuser) {
- my $perms = $c->cobrand->available_permissions;
+ my $perms = $cobrand->available_permissions;
return { map { %$_ } values %$perms };
}
+ my $body_id = $problem->bodies_str;
+
return unless $self->belongs_to_body($body_id);
my @permissions = grep { $_->body_id == $self->from_body->id } @{$self->body_permissions};
@@ -544,6 +588,17 @@ has categories => (
},
);
+has categories_string => (
+ is => 'ro',
+ lazy => 1,
+ default => sub {
+ my $self = shift;
+ my $csv = Text::CSV->new;
+ $csv->combine(@{$self->categories});
+ return $csv->string;
+ },
+);
+
sub set_last_active {
my $self = shift;
my $time = shift;
@@ -551,4 +606,19 @@ sub set_last_active {
$self->last_active($time or \'current_timestamp');
}
+has areas_hash => (
+ is => 'ro',
+ lazy => 1,
+ default => sub {
+ my $self = shift;
+ my %ids = map { $_ => 1 } @{$self->area_ids || []};
+ return \%ids;
+ },
+);
+
+sub in_area {
+ my ($self, $area) = @_;
+ return $self->areas_hash->{$area};
+}
+
1;
diff --git a/perllib/FixMyStreet/DB/Result/UserBodyPermission.pm b/perllib/FixMyStreet/DB/Result/UserBodyPermission.pm
index a118a1996..8fdabbdda 100644
--- a/perllib/FixMyStreet/DB/Result/UserBodyPermission.pm
+++ b/perllib/FixMyStreet/DB/Result/UserBodyPermission.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("user_body_permissions");
__PACKAGE__->add_columns(
"id",
@@ -44,8 +48,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2014-06-05 15:46:02
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:IWy2rYBU7WP6MyIkLYsc9Q
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:mcgnPaCmEuLWdzB3GuQiTg
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/Result/UserPlannedReport.pm b/perllib/FixMyStreet/DB/Result/UserPlannedReport.pm
index 1e893c7a9..cd1716f02 100644
--- a/perllib/FixMyStreet/DB/Result/UserPlannedReport.pm
+++ b/perllib/FixMyStreet/DB/Result/UserPlannedReport.pm
@@ -8,7 +8,11 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-__PACKAGE__->load_components("FilterColumn", "InflateColumn::DateTime", "EncodedColumn");
+__PACKAGE__->load_components(
+ "FilterColumn",
+ "FixMyStreet::InflateColumn::DateTime",
+ "FixMyStreet::EncodedColumn",
+);
__PACKAGE__->table("user_planned_reports");
__PACKAGE__->add_columns(
"id",
@@ -47,8 +51,8 @@ __PACKAGE__->belongs_to(
);
-# Created by DBIx::Class::Schema::Loader v0.07035 @ 2016-07-20 15:03:08
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:mv7koDhvZSBW/4aQivtpAQ
+# Created by DBIx::Class::Schema::Loader v0.07035 @ 2019-04-25 12:06:39
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:A9ICDFNVzkmd/erdtYdeVA
# You can replace this text with custom code or comments, and it will be preserved on regeneration
diff --git a/perllib/FixMyStreet/DB/ResultSet/Body.pm b/perllib/FixMyStreet/DB/ResultSet/Body.pm
index 0aa3e8240..4e9661d2e 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Body.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Body.pm
@@ -41,7 +41,7 @@ This restricts the ResultSet to bodies that are not marked as deleted.
sub active {
my $rs = shift;
- $rs->search({ deleted => 0 });
+ $rs->search({ 'me.deleted' => 0 });
}
=item translated
@@ -61,6 +61,22 @@ sub translated {
});
}
+=item with_parent_name
+
+This adds the parent name associated with each body to the ResultSet,
+in the parent_name column.
+
+=cut
+
+sub with_parent_name {
+ my $rs = shift;
+ $rs->search(undef, {
+ '+select' => [ 'parent.name' ],
+ '+as' => [ 'parent_name' ],
+ join => 'parent',
+ });
+}
+
=item with_area_count
This adds the number of areas associated with each body to the ResultSet,
@@ -78,10 +94,45 @@ sub with_area_count {
});
}
+=item with_defect_type_count
+
+This adds the number of defect types associated with each body to the
+ResultSet, in the defect_type_count column.
+
+=cut
+
+sub with_defect_type_count {
+ my $rs = shift;
+ $rs->search(undef, {
+ '+select' => [ { count => 'defect_types.name' } ],
+ '+as' => [ 'defect_type_count' ],
+ join => 'defect_types',
+ distinct => 1,
+ });
+}
+
+=item with_children_count
+
+This adds the number of children associated with each body to the
+ResultSet, in the children_count column.
+
+=cut
+
+sub with_children_count {
+ my $rs = shift;
+ $rs->search(undef, {
+ '+select' => [ { count => 'bodies.id' } ],
+ '+as' => [ 'children_count' ],
+ join => 'bodies',
+ distinct => 1,
+ });
+}
+
=item all_sorted
-This returns all results, as C<all()>, but sorted by their name column
-(which will be the translated names if present).
+This returns all results, as C<all()>, but sorted by their name (including
+the translated names, if present), and as simple hashrefs not objects, for
+performance reasons.
=back
@@ -89,8 +140,34 @@ This returns all results, as C<all()>, but sorted by their name column
sub all_sorted {
my $rs = shift;
- my @bodies = $rs->all;
- @bodies = sort { strcoll($a->name, $b->name) } @bodies;
+
+ # Use a HashRefInflator here to return simple hashrefs rather than full
+ # objects. This is quicker if you have a large number of bodies; note
+ # fetching only the columns you need provides even more of a speed up.
+ my @bodies = $rs->search(undef, {
+ result_class => 'DBIx::Class::ResultClass::HashRefInflator',
+ })->all;
+ @bodies = sort { strcoll($a->{msgstr} || $a->{name}, $b->{msgstr} || $b->{name}) } @bodies;
+
+ my $cobrand = $rs->result_source->schema->cobrand;
+
+ foreach my $body (@bodies) {
+ $body->{parent} = { id => $body->{parent}, name => $body->{parent_name} } if $body->{parent};
+
+ # DEPRECATED: url(c, query_params) -> url
+ $body->{url} = sub {
+ my ($c, $args) = @_;
+ return FixMyStreet::DB::Result::Body::_url($body, $cobrand, $args);
+ };
+
+ # DEPRECATED: get_column('area_count') -> area_count
+ next unless defined $body->{area_count};
+ $body->{get_column} = sub {
+ my $key = shift;
+ return $body->{$key};
+ };
+ }
+
return @bodies;
}
diff --git a/perllib/FixMyStreet/DB/ResultSet/Nearby.pm b/perllib/FixMyStreet/DB/ResultSet/Nearby.pm
index b075e3664..2ebe309e3 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Nearby.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Nearby.pm
@@ -10,31 +10,34 @@ sub to_body {
}
sub nearby {
- my ( $rs, $c, $dist, $ids, $limit, $mid_lat, $mid_lon, $categories, $states, $extra_params ) = @_;
+ my ( $rs, $c, %args ) = @_;
- unless ( $states ) {
- $states = FixMyStreet::DB::Result::Problem->visible_states();
+ unless ( $args{states} ) {
+ $args{states} = FixMyStreet::DB::Result::Problem->visible_states();
}
my $params = {
- state => [ keys %$states ],
+ state => [ keys %{$args{states}} ],
};
- $params->{id} = { -not_in => $ids }
- if $ids;
- $params->{category} = $categories if $categories && @$categories;
+ $params->{id} = { -not_in => $args{ids} }
+ if $args{ids};
+ $params->{category} = $args{categories} if $args{categories} && @{$args{categories}};
+
+ $params->{$c->stash->{report_age_field}} = { '>=', \"current_timestamp-'$args{report_age}'::interval" }
+ if $args{report_age};
FixMyStreet::DB::ResultSet::Problem->non_public_if_possible($params, $c);
$rs = $c->cobrand->problems_restriction($rs);
# Add in any optional extra query parameters
- $params = { %$params, %$extra_params } if $extra_params;
+ $params = { %$params, %{$args{extra}} } if $args{extra};
my $attrs = {
prefetch => 'problem',
- bind => [ $mid_lat, $mid_lon, $dist ],
+ bind => [ $args{latitude}, $args{longitude}, $args{distance} ],
order_by => [ 'distance', { -desc => 'created' } ],
- rows => $limit,
+ rows => $args{limit},
};
my @problems = mySociety::Locale::in_gb_locale { $rs->search( $params, $attrs )->all };
diff --git a/perllib/FixMyStreet/DB/ResultSet/Problem.pm b/perllib/FixMyStreet/DB/ResultSet/Problem.pm
index ef078ed08..37fc34057 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Problem.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Problem.pm
@@ -28,13 +28,23 @@ sub body_query {
sub non_public_if_possible {
my ($rs, $params, $c) = @_;
if ($c->user_exists) {
+ my $only_non_public = $c->stash->{only_non_public} ? 1 : 0;
if ($c->user->is_superuser) {
# See all reports, no restriction
- } elsif ($c->user->has_body_permission_to('report_inspect')) {
- $params->{'-or'} = [
- non_public => 0,
- $rs->body_query($c->user->from_body->id),
- ];
+ $params->{non_public} = 1 if $only_non_public;
+ } elsif ($c->user->has_body_permission_to('report_inspect') ||
+ $c->user->has_body_permission_to('report_mark_private')) {
+ if ($only_non_public) {
+ $params->{'-and'} = [
+ non_public => 1,
+ $rs->body_query($c->user->from_body->id),
+ ];
+ } else {
+ $params->{'-or'} = [
+ non_public => 0,
+ $rs->body_query($c->user->from_body->id),
+ ];
+ }
} else {
$params->{non_public} = 0;
}
@@ -57,6 +67,10 @@ sub to_body {
# Front page statistics
+sub _cache_timeout {
+ FixMyStreet->config('CACHE_TIMEOUT') // 3600;
+}
+
sub recent_fixed {
my $rs = shift;
my $key = "recent_fixed:$site_key";
@@ -66,7 +80,7 @@ sub recent_fixed {
state => [ FixMyStreet::DB::Result::Problem->fixed_states() ],
lastupdate => { '>', \"current_timestamp-'1 month'::interval" },
} )->count;
- Memcached::set($key, $result, 3600);
+ Memcached::set($key, $result, _cache_timeout());
}
return $result;
}
@@ -80,7 +94,7 @@ sub number_comments {
{ 'comments.state' => 'confirmed' },
{ join => 'comments' }
)->count;
- Memcached::set($key, $result, 3600);
+ Memcached::set($key, $result, _cache_timeout());
}
return $result;
}
@@ -95,7 +109,7 @@ sub recent_new {
state => [ FixMyStreet::DB::Result::Problem->visible_states() ],
confirmed => { '>', \"current_timestamp-'$interval'::interval" },
} )->count;
- Memcached::set($key, $result, 3600);
+ Memcached::set($key, $result, _cache_timeout());
}
return $result;
}
@@ -144,10 +158,10 @@ sub _recent {
# Need to reattach schema so that confirmed column gets reinflated.
$probs->[0]->result_source->schema( $rs->result_source->schema ) if $probs->[0];
# Catch any cached ones since hidden
- $probs = [ grep { ! $_->is_hidden } @$probs ];
+ $probs = [ grep { $_->photo && ! $_->is_hidden } @$probs ];
} else {
$probs = [ $rs->search( $query, $attrs )->all ];
- Memcached::set($key, $probs, 3600);
+ Memcached::set($key, $probs, _cache_timeout());
}
}
@@ -172,6 +186,9 @@ sub around_map {
latitude => { '>=', $p{min_lat}, '<', $p{max_lat} },
longitude => { '>=', $p{min_lon}, '<', $p{max_lon} },
};
+
+ $q->{$c->stash->{report_age_field}} = { '>=', \"current_timestamp-'$p{report_age}'::interval" } if
+ $p{report_age};
$q->{category} = $p{categories} if $p{categories} && @{$p{categories}};
$rs->non_public_if_possible($q, $c);
@@ -198,9 +215,9 @@ sub timeline {
return $rs->search(
{
-or => {
- created => { '>=', \"current_timestamp-'7 days'::interval" },
- confirmed => { '>=', \"current_timestamp-'7 days'::interval" },
- whensent => { '>=', \"current_timestamp-'7 days'::interval" },
+ 'me.created' => { '>=', \"current_timestamp-'7 days'::interval" },
+ 'me.confirmed' => { '>=', \"current_timestamp-'7 days'::interval" },
+ 'me.whensent' => { '>=', \"current_timestamp-'7 days'::interval" },
}
},
{
diff --git a/perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm b/perllib/FixMyStreet/DB/ResultSet/ReportExtraField.pm
index 1348df3c2..9c47b1894 100644
--- a/perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/ReportExtraField.pm
@@ -1,4 +1,4 @@
-package FixMyStreet::DB::ResultSet::ReportExtraFields;
+package FixMyStreet::DB::ResultSet::ReportExtraField;
use base 'DBIx::Class::ResultSet';
use strict;