aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/DB
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/DB')
-rw-r--r--perllib/FixMyStreet/DB/Result/Alert.pm5
-rw-r--r--perllib/FixMyStreet/DB/Result/Comment.pm9
-rw-r--r--perllib/FixMyStreet/DB/Result/Contact.pm5
-rw-r--r--perllib/FixMyStreet/DB/Result/Nearby.pm5
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm45
-rw-r--r--perllib/FixMyStreet/DB/Result/Questionnaire.pm2
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Alert.pm2
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/AlertType.pm266
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Comment.pm2
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Problem.pm309
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm104
11 files changed, 41 insertions, 713 deletions
diff --git a/perllib/FixMyStreet/DB/Result/Alert.pm b/perllib/FixMyStreet/DB/Result/Alert.pm
index 35cce8368..2a52a7bca 100644
--- a/perllib/FixMyStreet/DB/Result/Alert.pm
+++ b/perllib/FixMyStreet/DB/Result/Alert.pm
@@ -70,7 +70,7 @@ __PACKAGE__->belongs_to(
# You can replace this text with custom code or comments, and it will be preserved on regeneration
-use Moose;
+use Moo;
use namespace::clean -except => [ 'meta' ];
with 'FixMyStreet::Roles::Abuser';
@@ -113,7 +113,4 @@ sub disable {
return 1;
}
-# need the inline_constuctor bit as we don't inherit from Moose
-__PACKAGE__->meta->make_immutable( inline_constructor => 0 );
-
1;
diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm
index 0caaa8968..41e8cf315 100644
--- a/perllib/FixMyStreet/DB/Result/Comment.pm
+++ b/perllib/FixMyStreet/DB/Result/Comment.pm
@@ -96,8 +96,8 @@ __PACKAGE__->belongs_to(
__PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn");
__PACKAGE__->rabx_column('extra');
-use Image::Size;
-use Moose;
+use Moo;
+use Utils::Photo;
use namespace::clean -except => [ 'meta' ];
with 'FixMyStreet::Roles::Abuser';
@@ -156,7 +156,7 @@ Returns a hashref of details of any attached photo for use in templates.
sub get_photo_params {
my $self = shift;
- return FixMyStreet::App::get_photo_params($self, 'c');
+ return Utils::Photo::get_photo_params($self, 'c');
}
=head2 meta_problem_state
@@ -214,7 +214,4 @@ __PACKAGE__->might_have(
{ cascade_copy => 0, cascade_delete => 1 },
);
-# we need the inline_constructor bit as we don't inherit from Moose
-__PACKAGE__->meta->make_immutable( inline_constructor => 0 );
-
1;
diff --git a/perllib/FixMyStreet/DB/Result/Contact.pm b/perllib/FixMyStreet/DB/Result/Contact.pm
index 2fbb0716d..dab5432c6 100644
--- a/perllib/FixMyStreet/DB/Result/Contact.pm
+++ b/perllib/FixMyStreet/DB/Result/Contact.pm
@@ -63,12 +63,9 @@ __PACKAGE__->belongs_to(
__PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn");
__PACKAGE__->rabx_column('extra');
-use Moose;
+use Moo;
use namespace::clean -except => [ 'meta' ];
with 'FixMyStreet::Roles::Extra';
-# we need the inline_constructor bit as we don't inherit from Moose
-__PACKAGE__->meta->make_immutable( inline_constructor => 0 );
-
1;
diff --git a/perllib/FixMyStreet/DB/Result/Nearby.pm b/perllib/FixMyStreet/DB/Result/Nearby.pm
index d3d228788..adeba703a 100644
--- a/perllib/FixMyStreet/DB/Result/Nearby.pm
+++ b/perllib/FixMyStreet/DB/Result/Nearby.pm
@@ -6,7 +6,7 @@ use strict;
use warnings;
use base 'DBIx::Class::Core';
-use Moose;
+use Moo;
use namespace::clean -except => [ 'meta' ];
__PACKAGE__->table( 'NONE' );
@@ -27,7 +27,4 @@ __PACKAGE__->belongs_to(
__PACKAGE__->result_source_instance
->name( \'problem_find_nearby(?,?,?)' );
-# we need the inline_constructor bit as we don't inherit from Moose
-__PACKAGE__->meta->make_immutable( inline_constructor => 0 );
-
1;
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm
index 3b7f8bcfd..f2df41f09 100644
--- a/perllib/FixMyStreet/DB/Result/Problem.pm
+++ b/perllib/FixMyStreet/DB/Result/Problem.pm
@@ -157,10 +157,10 @@ __PACKAGE__->load_components("+FixMyStreet::DB::RABXColumn");
__PACKAGE__->rabx_column('extra');
__PACKAGE__->rabx_column('geocode');
-use Image::Size;
-use Moose;
+use Moo;
use namespace::clean -except => [ 'meta' ];
use Utils;
+use Utils::Photo;
with 'FixMyStreet::Roles::Abuser',
'FixMyStreet::Roles::Extra';
@@ -462,7 +462,7 @@ sub bodies($) {
my $self = shift;
return {} unless $self->bodies_str;
my $bodies = $self->bodies_str_ids;
- my @bodies = FixMyStreet::App->model('DB::Body')->search({ id => $bodies })->all;
+ my @bodies = $self->result_source->schema->resultset('Body')->search({ id => $bodies })->all;
return { map { $_->id => $_ } @bodies };
}
@@ -477,6 +477,11 @@ sub url {
return "/report/" . $self->id;
}
+sub admin_url {
+ my ($self, $cobrand) = @_;
+ return $cobrand->admin_base_url . '/report_edit/' . $self->id;
+}
+
=head2 get_photo_params
Returns a hashref of details of the attached photo, if any, for use in templates.
@@ -491,7 +496,7 @@ sub get_photo_params {
# use Carp 'cluck';
# cluck "get_photo_params called"; # TEMPORARY die to make sure I've done right thing with Zurich templates
my $self = shift;
- return FixMyStreet::App::get_photo_params($self, 'id');
+ return Utils::Photo::get_photo_params($self, 'id');
}
=head2 is_open
@@ -628,7 +633,7 @@ sub body {
$body = join( _(' and '),
map {
my $name = $_->name;
- if ($c and mySociety::Config::get('AREA_LINKS_FROM_PROBLEMS')) {
+ if ($c and FixMyStreet->config('AREA_LINKS_FROM_PROBLEMS')) {
'<a href="' . $_->url($c) . '">' . $name . '</a>';
} else {
$name;
@@ -648,7 +653,7 @@ order of title.
sub response_templates {
my $problem = shift;
- return FixMyStreet::App->model('DB::ResponseTemplate')->search(
+ return $problem->result_source->schema->resultset('ResponseTemplate')->search(
{
body_id => $problem->bodies_str_ids
},
@@ -754,20 +759,17 @@ sub update_from_open311_service_request {
$status_notes = $request->{status_notes};
}
- my $update = FixMyStreet::App->model('DB::Comment')->new(
- {
- problem_id => $self->id,
- state => 'confirmed',
- created => $updated || \'current_timestamp',
- confirmed => \'current_timestamp',
- text => $status_notes,
- mark_open => 0,
- mark_fixed => 0,
- user => $system_user,
- anonymous => 0,
- name => $body->name,
- }
- );
+ my $update = $self->new_related(comments => {
+ state => 'confirmed',
+ created => $updated || \'current_timestamp',
+ confirmed => \'current_timestamp',
+ text => $status_notes,
+ mark_open => 0,
+ mark_fixed => 0,
+ user => $system_user,
+ anonymous => 0,
+ name => $body->name,
+ });
my $w3c = DateTime::Format::W3CDTF->new;
my $req_time = $w3c->parse_datetime( $request->{updated_datetime} );
@@ -894,7 +896,4 @@ sub get_time_spent {
return $admin_logs ? $admin_logs->get_column('sum_time_spent') : 0;
}
-# we need the inline_constructor bit as we don't inherit from Moose
-__PACKAGE__->meta->make_immutable( inline_constructor => 0 );
-
1;
diff --git a/perllib/FixMyStreet/DB/Result/Questionnaire.pm b/perllib/FixMyStreet/DB/Result/Questionnaire.pm
index 6f2941546..30f2ab7ce 100644
--- a/perllib/FixMyStreet/DB/Result/Questionnaire.pm
+++ b/perllib/FixMyStreet/DB/Result/Questionnaire.pm
@@ -43,7 +43,7 @@ __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
-use Moose;
+use Moo;
use namespace::clean -except => [ 'meta' ];
my $stz = sub {
diff --git a/perllib/FixMyStreet/DB/ResultSet/Alert.pm b/perllib/FixMyStreet/DB/ResultSet/Alert.pm
index bb1c61141..1866e9b06 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Alert.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Alert.pm
@@ -8,7 +8,7 @@ sub timeline_created {
my ( $rs, $restriction ) = @_;
my $prefetch =
- FixMyStreet::App->model('DB')->schema->storage->sql_maker->quote_char ?
+ $rs->result_source->storage->sql_maker->quote_char ?
[ qw/alert_type user/ ] :
[ qw/alert_type/ ];
diff --git a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm
index 25c727e25..a801600ea 100644
--- a/perllib/FixMyStreet/DB/ResultSet/AlertType.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/AlertType.pm
@@ -4,272 +4,10 @@ use base 'DBIx::Class::ResultSet';
use strict;
use warnings;
-use mySociety::DBHandle qw(dbh);
-use mySociety::Gaze;
-use mySociety::Locale;
-use mySociety::MaPit;
-use IO::String;
-use RABX;
-
-# Child must have confirmed, id, email, state(!) columns
-# If parent/child, child table must also have name and text
-# and foreign key to parent must be PARENT_id
sub email_alerts ($) {
my ( $rs ) = @_;
-
- my $q = $rs->search( { ref => { -not_like => '%local_problems%' } } );
- while (my $alert_type = $q->next) {
- my $ref = $alert_type->ref;
- my $head_table = $alert_type->head_table;
- my $item_table = $alert_type->item_table;
- my $query = 'select alert.id as alert_id, alert.user_id as alert_user_id, alert.lang as alert_lang, alert.cobrand as alert_cobrand,
- alert.cobrand_data as alert_cobrand_data, alert.parameter as alert_parameter, alert.parameter2 as alert_parameter2, ';
- if ($head_table) {
- $query .= "
- $item_table.id as item_id, $item_table.text as item_text,
- $item_table.name as item_name, $item_table.anonymous as item_anonymous,
- $item_table.confirmed as item_confirmed,
- $head_table.*
- from alert, $item_table, $head_table
- where alert.parameter::integer = $head_table.id
- and $item_table.${head_table}_id = $head_table.id
- ";
- } else {
- $query .= " $item_table.*,
- $item_table.id as item_id
- from alert, $item_table
- where 1 = 1";
- }
- $query .= "
- and alert_type='$ref' and whendisabled is null and $item_table.confirmed >= whensubscribed
- and $item_table.confirmed >= current_timestamp - '7 days'::interval
- and (select whenqueued from alert_sent where alert_sent.alert_id = alert.id and alert_sent.parameter::integer = $item_table.id) is null
- and $item_table.user_id <> alert.user_id
- and " . $alert_type->item_where . "
- and alert.confirmed = 1
- order by alert.id, $item_table.confirmed";
- # XXX Ugh - needs work
- $query =~ s/\?/alert.parameter/ if ($query =~ /\?/);
- $query =~ s/\?/alert.parameter2/ if ($query =~ /\?/);
-
- $query = dbh()->prepare($query);
- $query->execute();
- my $last_alert_id;
- my %data = ( template => $alert_type->template, data => '' );
- while (my $row = $query->fetchrow_hashref) {
-
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->{alert_cobrand})->new();
- $cobrand->set_lang_and_domain( $row->{alert_lang}, 1, FixMyStreet->path_to('locale')->stringify );
-
- # Cobranded and non-cobranded messages can share a database. In this case, the conf file
- # should specify a vhost to send the reports for each cobrand, so that they don't get sent
- # more than once if there are multiple vhosts running off the same database. The email_host
- # call checks if this is the host that sends mail for this cobrand.
- next unless $cobrand->email_host;
-
- # this is for the new_updates alerts
- next if $row->{non_public} and $row->{user_id} != $row->{alert_user_id};
-
- FixMyStreet::App->model('DB::AlertSent')->create( {
- alert_id => $row->{alert_id},
- parameter => $row->{item_id},
- } );
- if ($last_alert_id && $last_alert_id != $row->{alert_id}) {
- _send_aggregated_alert_email(%data);
- %data = ( template => $alert_type->template, data => '' );
- }
-
- # create problem status message for the templates
- if ( FixMyStreet::DB::Result::Problem::fixed_states()->{$row->{state}} ) {
- $data{state_message} = _("This report is currently marked as fixed.");
- } elsif ( FixMyStreet::DB::Result::Problem::closed_states()->{$row->{state}} ) {
- $data{state_message} = _("This report is currently marked as closed.")
- } else {
- $data{state_message} = _("This report is currently marked as open.");
- }
-
- my $url = $cobrand->base_url_for_report($row);
- # this is currently only for new_updates
- if ($row->{item_text}) {
- if ( $cobrand->moniker ne 'zurich' && $row->{alert_user_id} == $row->{user_id} ) {
- # This is an alert to the same user who made the report - make this a login link
- # Don't bother with Zurich which has no accounts
- my $user = FixMyStreet::App->model('DB::User')->find( {
- id => $row->{alert_user_id}
- } );
- $data{alert_email} = $user->email;
- my $token_obj = FixMyStreet::App->model('DB::Token')->create( {
- scope => 'alert_to_reporter',
- data => {
- id => $row->{id},
- }
- } );
- $data{problem_url} = $url . "/R/" . $token_obj->token;
- } else {
- $data{problem_url} = $url . "/report/" . $row->{id};
- }
- $data{data} .= $row->{item_name} . ' : ' if $row->{item_name} && !$row->{item_anonymous};
- if ( $cobrand->include_time_in_update_alerts ) {
- my $parser = DateTime::Format::Pg->new();
- my $dt = $parser->parse_timestamp( $row->{item_confirmed} );
- # We need to always set this otherwise we end up with the DateTime
- # object being in the floating timezone in which case applying a
- # subsequent timezone set will have no effect.
- # this is basically recreating the code from the inflate wrapper
- # in the database model.
- FixMyStreet->set_time_zone($dt);
- $data{data} .= $cobrand->prettify_dt( $dt, 'alert' ) . "\n\n";
- }
- $data{data} .= $row->{item_text} . "\n\n------\n\n";
- # this is ward and council problems
- } else {
- $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}\n\n";
- if ( exists $row->{geocode} && $row->{geocode} && $ref =~ /ward|council/ ) {
- my $nearest_st = _get_address_from_gecode( $row->{geocode} );
- $data{data} .= $nearest_st if $nearest_st;
- }
- $data{data} .= "\n\n------\n\n";
- }
- if (!$data{alert_user_id}) {
- %data = (%data, %$row);
- if ($ref eq 'area_problems' || $ref eq 'council_problems' || $ref eq 'ward_problems') {
- my $va_info = mySociety::MaPit::call('area', $row->{alert_parameter});
- $data{area_name} = $va_info->{name};
- }
- if ($ref eq 'ward_problems') {
- my $va_info = mySociety::MaPit::call('area', $row->{alert_parameter2});
- $data{ward_name} = $va_info->{name};
- }
- }
- $data{cobrand} = $row->{alert_cobrand};
- $data{cobrand_data} = $row->{alert_cobrand_data};
- $data{lang} = $row->{alert_lang};
- $last_alert_id = $row->{alert_id};
- }
- if ($last_alert_id) {
- _send_aggregated_alert_email(%data);
- }
- }
-
- # Nearby done separately as the table contains the parameters
- my $template = $rs->find( { ref => 'local_problems' } )->template;
- my $query = FixMyStreet::App->model('DB::Alert')->search( {
- alert_type => 'local_problems',
- whendisabled => undef,
- confirmed => 1
- }, {
- order_by => 'id'
- } );
- while (my $alert = $query->next) {
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($alert->cobrand)->new();
- next unless $cobrand->email_host;
- next if $alert->is_from_abuser;
-
- my $longitude = $alert->parameter;
- my $latitude = $alert->parameter2;
- my $d = mySociety::Gaze::get_radius_containing_population($latitude, $longitude, 200000);
- # Convert integer to GB locale string (with a ".")
- $d = mySociety::Locale::in_gb_locale {
- sprintf("%f", int($d*10+0.5)/10);
- };
- my $states = "'" . join( "', '", FixMyStreet::DB::Result::Problem::visible_states() ) . "'";
- my %data = ( template => $template, data => '', alert_id => $alert->id, alert_email => $alert->user->email, lang => $alert->lang, cobrand => $alert->cobrand, cobrand_data => $alert->cobrand_data );
- my $q = "select problem.id, problem.bodies_str, problem.postcode, problem.geocode, problem.title from problem_find_nearby(?, ?, ?) as nearby, problem, users
- where nearby.problem_id = problem.id
- and problem.user_id = users.id
- and problem.state in ($states)
- and problem.non_public = 'f'
- and problem.confirmed >= ? and problem.confirmed >= current_timestamp - '7 days'::interval
- and (select whenqueued from alert_sent where alert_sent.alert_id = ? and alert_sent.parameter::integer = problem.id) is null
- and users.email <> ?
- order by confirmed desc";
- $q = dbh()->prepare($q);
- $q->execute($latitude, $longitude, $d, $alert->whensubscribed, $alert->id, $alert->user->email);
- while (my $row = $q->fetchrow_hashref) {
- FixMyStreet::App->model('DB::AlertSent')->create( {
- alert_id => $alert->id,
- parameter => $row->{id},
- } );
- my $url = $cobrand->base_url_for_report($row);
- $data{data} .= $url . "/report/" . $row->{id} . " - $row->{title}\n\n";
- if ( exists $row->{geocode} && $row->{geocode} ) {
- my $nearest_st = _get_address_from_gecode( $row->{geocode} );
- $data{data} .= $nearest_st if $nearest_st;
- }
- $data{data} .= "\n\n------\n\n";
- }
- _send_aggregated_alert_email(%data) if $data{data};
- }
-}
-
-sub _send_aggregated_alert_email(%) {
- my %data = @_;
-
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($data{cobrand})->new();
-
- $cobrand->set_lang_and_domain( $data{lang}, 1, FixMyStreet->path_to('locale')->stringify );
-
- if (!$data{alert_email}) {
- my $user = FixMyStreet::App->model('DB::User')->find( {
- id => $data{alert_user_id}
- } );
- $data{alert_email} = $user->email;
- }
-
- my ($domain) = $data{alert_email} =~ m{ @ (.*) \z }x;
- return if FixMyStreet::App->model('DB::Abuse')->search( {
- email => [ $data{alert_email}, $domain ]
- } )->first;
-
- my $token = FixMyStreet::App->model("DB::Token")->new_result( {
- scope => 'alert',
- data => {
- id => $data{alert_id},
- type => 'unsubscribe',
- email => $data{alert_email},
- }
- } );
- $data{unsubscribe_url} = $cobrand->base_url( $data{cobrand_data} ) . '/A/' . $token->token;
-
- my $template = FixMyStreet->get_email_template($cobrand->moniker, $data{lang}, "$data{template}.txt");
-
- my $result = FixMyStreet::App->send_email_cron(
- {
- _template_ => $template,
- _parameters_ => \%data,
- To => $data{alert_email},
- },
- undef,
- 0,
- $cobrand,
- $data{lang}
- );
-
- unless ($result) {
- $token->insert();
- } else {
- print "Failed to send alert $data{alert_id}!";
- }
-}
-
-sub _get_address_from_gecode {
- my $geocode = shift;
-
- return '' unless defined $geocode;
- utf8::encode($geocode) if utf8::is_utf8($geocode);
- my $h = new IO::String($geocode);
- my $data = RABX::wire_rd($h);
-
- my $str = '';
-
- my $address = $data->{resourceSets}[0]{resources}[0]{address};
- my @address;
- push @address, $address->{addressLine} if $address->{addressLine} && $address->{addressLine} ne 'Street';
- push @address, $address->{locality} if $address->{locality};
- $str .= sprintf(_("Nearest road to the pin placed on the map (automatically generated by Bing Maps): %s\n\n"),
- join( ', ', @address ) ) if @address;
-
- return $str;
+ require FixMyStreet::Script::Alerts;
+ FixMyStreet::Script::Alerts::send(@_);
}
1;
diff --git a/perllib/FixMyStreet/DB/ResultSet/Comment.pm b/perllib/FixMyStreet/DB/ResultSet/Comment.pm
index 1b6afb819..3059baab1 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Comment.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Comment.pm
@@ -14,7 +14,7 @@ sub timeline {
my ( $rs, $body_restriction ) = @_;
my $prefetch =
- FixMyStreet::App->model('DB')->schema->storage->sql_maker->quote_char ?
+ $rs->result_source->storage->sql_maker->quote_char ?
[ qw/user/ ] :
[];
diff --git a/perllib/FixMyStreet/DB/ResultSet/Problem.pm b/perllib/FixMyStreet/DB/ResultSet/Problem.pm
index e9f5d0f8e..f82f0135c 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Problem.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Problem.pm
@@ -4,14 +4,9 @@ use base 'DBIx::Class::ResultSet';
use strict;
use warnings;
-use CronFns;
-
-use Utils;
-use mySociety::Config;
-use mySociety::MaPit;
-
-use FixMyStreet::App;
-use FixMyStreet::SendReport;
+use Memcached;
+use mySociety::Locale;
+use FixMyStreet::DB;
my $site_key;
@@ -173,7 +168,7 @@ sub timeline {
my ( $rs ) = @_;
my $prefetch =
- FixMyStreet::App->model('DB')->schema->storage->sql_maker->quote_char ?
+ $rs->result_source->storage->sql_maker->quote_char ?
[ qw/user/ ] :
[];
@@ -235,302 +230,10 @@ sub categories_summary {
return \%categories;
}
-sub get_admin_url {
- my ($rs, $cobrand, $row) = @_;
- return $cobrand->admin_base_url . '/report_edit/' . $row->id;
-}
-
sub send_reports {
my ( $rs, $site_override ) = @_;
-
- # Set up site, language etc.
- my ($verbose, $nomail, $debug_mode) = CronFns::options();
-
- my $base_url = mySociety::Config::get('BASE_URL');
- my $site = $site_override || CronFns::site($base_url);
-
- my $states = [ 'confirmed', 'fixed' ];
- $states = [ 'unconfirmed', 'confirmed', 'in progress', 'planned', 'closed', 'investigating' ] if $site eq 'zurich';
- my $unsent = $rs->search( {
- state => $states,
- whensent => undef,
- bodies_str => { '!=', undef },
- } );
- my (%notgot, %note);
-
- my $send_report = FixMyStreet::SendReport->new();
- my $senders = $send_report->get_senders;
-
- my $debug_unsent_count = 0;
- debug_print("starting to loop through unsent problem reports...") if $debug_mode;
- while (my $row = $unsent->next) {
-
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new();
-
- if ($debug_mode) {
- $debug_unsent_count++;
- print "\n";
- debug_print("state=" . $row->state . ", bodies_str=" . $row->bodies_str . ($row->cobrand? ", cobrand=" . $row->cobrand : ""), $row->id);
- }
-
- # Cobranded and non-cobranded messages can share a database. In this case, the conf file
- # should specify a vhost to send the reports for each cobrand, so that they don't get sent
- # more than once if there are multiple vhosts running off the same database. The email_host
- # call checks if this is the host that sends mail for this cobrand.
- if (! $cobrand->email_host()) {
- debug_print("skipping because this host does not send reports for cobrand " . $cobrand->moniker, $row->id) if $debug_mode;
- next;
- }
-
- $cobrand->set_lang_and_domain($row->lang, 1);
- if ( $row->is_from_abuser) {
- $row->update( { state => 'hidden' } );
- debug_print("hiding because its sender is flagged as an abuser", $row->id) if $debug_mode;
- next;
- } elsif ( $row->title =~ /app store test/i ) {
- $row->update( { state => 'hidden' } );
- debug_print("hiding because it is an app store test message", $row->id) if $debug_mode;
- next;
- }
-
- # Template variables for the email
- my $email_base_url = $cobrand->base_url_for_report($row);
- my %h = map { $_ => $row->$_ } qw/id title detail name category latitude longitude used_map/;
- map { $h{$_} = $row->user->$_ || '' } qw/email phone/;
- $h{confirmed} = DateTime::Format::Pg->format_datetime( $row->confirmed->truncate (to => 'second' ) )
- if $row->confirmed;
-
- $h{query} = $row->postcode;
- $h{url} = $email_base_url . $row->url;
- $h{admin_url} = $rs->get_admin_url($cobrand, $row);
- $h{phone_line} = $h{phone} ? _('Phone:') . " $h{phone}\n\n" : '';
- if ($row->photo) {
- $h{has_photo} = _("This web page also contains a photo of the problem, provided by the user.") . "\n\n";
- $h{image_url} = $email_base_url . '/photo/' . $row->id . '.full.jpeg';
- } else {
- $h{has_photo} = '';
- $h{image_url} = '';
- }
- $h{fuzzy} = $row->used_map ? _('To view a map of the precise location of this issue')
- : _('The user could not locate the problem on a map, but to see the area around the location they entered');
- $h{closest_address} = '';
-
- if ( $row->used_map ) {
- $h{closest_address} = $cobrand->find_closest( $h{latitude}, $h{longitude}, $row );
- }
-
- if ( $cobrand->allow_anonymous_reports &&
- $row->user->email eq $cobrand->anonymous_account->{'email'}
- ) {
- $h{anonymous_report} = 1;
- $h{user_details} = _('This report was submitted anonymously');
- } else {
- $h{user_details} = sprintf(_('Name: %s'), $row->name) . "\n\n";
- $h{user_details} .= sprintf(_('Email: %s'), $row->user->email) . "\n\n";
- }
-
- $h{easting_northing} = '';
-
- if ($cobrand->can('process_additional_metadata_for_email')) {
- $cobrand->process_additional_metadata_for_email($row, \%h);
- }
-
- my $bodies = FixMyStreet::App->model("DB::Body")->search(
- { id => $row->bodies_str_ids },
- { order_by => 'name' },
- );
-
- my $missing;
- if ($row->bodies_missing) {
- my @missing = FixMyStreet::App->model("DB::Body")->search(
- { id => [ split /,/, $row->bodies_missing ] },
- { order_by => 'name' }
- )->get_column('name')->all;
- $missing = join(' / ', @missing) if @missing;
- }
-
- my @dear;
- my %reporters = ();
- while (my $body = $bodies->next) {
- my $sender_info = $cobrand->get_body_sender( $body, $row->category );
- my $sender = "FixMyStreet::SendReport::" . $sender_info->{method};
-
- if ( ! exists $senders->{ $sender } ) {
- warn sprintf "No such sender [ $sender ] for body %s ( %d )", $body->name, $body->id;
- next;
- }
- $reporters{ $sender } ||= $sender->new();
-
- if ( $reporters{ $sender }->should_skip( $row ) ) {
- debug_print("skipped by sender " . $sender_info->{method} . " (might be due to previous failed attempts?)", $row->id) if $debug_mode;
- } else {
- debug_print("OK, adding recipient body " . $body->id . ":" . $body->name . ", " . $body->send_method, $row->id) if $debug_mode;
- push @dear, $body->name;
- $reporters{ $sender }->add_body( $body, $sender_info->{config} );
- }
-
- # If we are in the UK include eastings and northings, and nearest stuff
- if ( $cobrand->country eq 'GB' && !$h{easting} ) {
- my $coordsyst = 'G';
- my $first_area = $body->body_areas->first->area_id;
- my $area_info = mySociety::MaPit::call('area', $first_area);
- $coordsyst = 'I' if $area_info->{type} eq 'LGD';
-
- ( $h{easting}, $h{northing} ) = Utils::convert_latlon_to_en( $h{latitude}, $h{longitude}, $coordsyst );
-
- # email templates don't have conditionals so we need to format this here
- $h{easting_northing} = "Easting/Northing";
- $h{easting_northing} .= " (IE)" if $coordsyst eq 'I';
- $h{easting_northing} .= ": $h{easting}/$h{northing}\n\n";
- }
- }
-
- unless ( keys %reporters ) {
- die 'Report not going anywhere for ID ' . $row->id . '!';
- }
-
- unless (@dear) {
- debug_print("can't send because sender count is zero", $row->id) if $debug_mode;
- next;
- }
-
- if ($h{category} eq _('Other')) {
- $h{category_footer} = _('this type of local problem');
- $h{category_line} = '';
- } else {
- $h{category_footer} = "'" . $h{category} . "'";
- $h{category_line} = sprintf(_("Category: %s"), $h{category}) . "\n\n";
- }
-
- if ( $row->subcategory ) {
- $h{subcategory_line} = sprintf(_("Subcategory: %s"), $row->subcategory) . "\n\n";
- } else {
- $h{subcategory_line} = "\n\n";
- }
-
- $h{bodies_name} = join(_(' and '), @dear);
- if ($h{category} eq _('Other')) {
- $h{multiple} = @dear>1 ? "[ " . _("This email has been sent to both councils covering the location of the problem, as the user did not categorise it; please ignore it if you're not the correct council to deal with the issue, or let us know what category of problem this is so we can add it to our system.") . " ]\n\n"
- : '';
- } else {
- $h{multiple} = @dear>1 ? "[ " . _("This email has been sent to several councils covering the location of the problem, as the category selected is provided for all of them; please ignore it if you're not the correct council to deal with the issue.") . " ]\n\n"
- : '';
- }
- $h{missing} = '';
- if ($missing) {
- $h{missing} = '[ '
- . sprintf(_('We realise this problem might be the responsibility of %s; however, we don\'t currently have any contact details for them. If you know of an appropriate contact address, please do get in touch.'), $missing)
- . " ]\n\n";
- }
-
- if (mySociety::Config::get('STAGING_SITE') && !mySociety::Config::get('SEND_REPORTS_ON_STAGING')) {
- # on a staging server send emails to ourselves rather than the bodies
- %reporters = map { $_ => $reporters{$_} } grep { /FixMyStreet::SendReport::(Email|EmptyHomes)/ } keys %reporters;
- unless (%reporters) {
- %reporters = ( 'FixMyStreet::SendReport::Email' => FixMyStreet::SendReport::Email->new() );
- }
- }
-
- # Multiply results together, so one success counts as a success.
- my $result = -1;
-
- for my $sender ( keys %reporters ) {
- debug_print("sending using " . $sender, $row->id) if $debug_mode;
- $result *= $reporters{ $sender }->send( $row, \%h );
- if ( $reporters{ $sender }->unconfirmed_counts) {
- foreach my $e (keys %{ $reporters{ $sender }->unconfirmed_counts } ) {
- foreach my $c (keys %{ $reporters{ $sender }->unconfirmed_counts->{$e} }) {
- $notgot{$e}{$c} += $reporters{ $sender }->unconfirmed_counts->{$e}{$c};
- }
- }
- %note = (
- %note,
- %{ $reporters{ $sender }->unconfirmed_notes }
- );
- }
- }
-
- unless ($result) {
- $row->update( {
- whensent => \'current_timestamp',
- lastupdate => \'current_timestamp',
- } );
- if ( $cobrand->report_sent_confirmation_email && !$h{anonymous_report}) {
- _send_report_sent_email( $row, \%h, $nomail, $cobrand );
- }
- debug_print("send successful: OK", $row->id) if $debug_mode;
- } else {
- my @errors;
- for my $sender ( keys %reporters ) {
- unless ( $reporters{ $sender }->success ) {
- push @errors, $reporters{ $sender }->error;
- }
- }
- $row->update_send_failed( join( '|', @errors ) );
- debug_print("send FAILED: " . join( '|', @errors ), $row->id) if $debug_mode;
- }
- }
- if ($debug_mode) {
- print "\n";
- if ($debug_unsent_count) {
- debug_print("processed all unsent reports (total: $debug_unsent_count)");
- } else {
- debug_print("no unsent reports were found (must have whensent=null and suitable bodies_str & state) -- nothing to send");
- }
- }
-
- if ($verbose || $debug_mode) {
- print "Council email addresses that need checking:\n" if keys %notgot;
- foreach my $e (keys %notgot) {
- foreach my $c (keys %{$notgot{$e}}) {
- print " " . $notgot{$e}{$c} . " problem, to $e category $c (" . $note{$e}{$c}. ")\n";
- }
- }
- my $sending_errors = '';
- my $unsent = $rs->search( {
- state => [ 'confirmed', 'fixed' ],
- whensent => undef,
- bodies_str => { '!=', undef },
- send_fail_count => { '>', 0 }
- } );
- while (my $row = $unsent->next) {
- my $base_url = mySociety::Config::get('BASE_URL');
- $sending_errors .= "* " . $base_url . "/report/" . $row->id . ", failed "
- . $row->send_fail_count . " times, last at " . $row->send_fail_timestamp
- . ", reason " . $row->send_fail_reason . "\n";
- }
- if ($sending_errors) {
- print "The following reports had problems sending:\n$sending_errors";
- }
- }
-}
-
-sub _send_report_sent_email {
- my $row = shift;
- my $h = shift;
- my $nomail = shift;
- my $cobrand = shift;
-
- my $template = FixMyStreet->get_email_template($row->cobrand, $row->lang, 'confirm_report_sent.txt');
-
- FixMyStreet::App->send_email_cron(
- {
- _template_ => $template,
- _parameters_ => $h,
- To => $row->user->email,
- From => [ mySociety::Config::get('CONTACT_EMAIL'), $cobrand->contact_name ],
- },
- mySociety::Config::get('CONTACT_EMAIL'),
- $nomail,
- $cobrand
- );
-}
-
-sub debug_print {
- my $msg = shift;
- my $id = shift || '';
- $id = "report $id: " if $id;
- print "[] $id$msg\n";
+ require FixMyStreet::Script::Reports;
+ FixMyStreet::Script::Reports::send($site_override);
}
1;
diff --git a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm
index bf1c68c49..6a1ce0d78 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm
@@ -3,111 +3,11 @@ use base 'DBIx::Class::ResultSet';
use strict;
use warnings;
-use Encode;
-use Utils;
sub send_questionnaires {
my ( $rs, $params ) = @_;
- $rs->send_questionnaires_period( '4 weeks', $params );
- $rs->send_questionnaires_period( '26 weeks', $params )
- if $params->{site} eq 'emptyhomes';
-}
-
-sub send_questionnaires_period {
- my ( $rs, $period, $params ) = @_;
-
- # Select all problems that need a questionnaire email sending
- my $q_params = {
- state => [ FixMyStreet::DB::Result::Problem::visible_states() ],
- whensent => [
- '-and',
- { '!=', undef },
- { '<', \"current_timestamp - '$period'::interval" },
- ],
- send_questionnaire => 1,
- };
- # FIXME Do these a bit better...
- if ($params->{site} eq 'emptyhomes' && $period eq '4 weeks') {
- $q_params->{'(select max(whensent) from questionnaire where me.id=problem_id)'} = undef;
- } elsif ($params->{site} eq 'emptyhomes' && $period eq '26 weeks') {
- $q_params->{'(select max(whensent) from questionnaire where me.id=problem_id)'} = { '!=', undef };
- } else {
- $q_params->{'-or'} = [
- '(select max(whensent) from questionnaire where me.id=problem_id)' => undef,
- '(select max(whenanswered) from questionnaire where me.id=problem_id)' => { '<', \"current_timestamp - '$period'::interval" }
- ];
- }
-
- my $unsent = FixMyStreet::App->model('DB::Problem')->search( $q_params, {
- order_by => { -desc => 'confirmed' }
- } );
-
- while (my $row = $unsent->next) {
-
- my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new();
- $cobrand->set_lang_and_domain($row->lang, 1);
-
- # Not all cobrands send questionnaires
- next unless $cobrand->send_questionnaires;
- next if $row->is_from_abuser;
-
- # Cobranded and non-cobranded messages can share a database. In this case, the conf file
- # should specify a vhost to send the reports for each cobrand, so that they don't get sent
- # more than once if there are multiple vhosts running off the same database. The email_host
- # call checks if this is the host that sends mail for this cobrand.
- next unless $cobrand->email_host;
-
- my $template;
- if ($params->{site} eq 'emptyhomes') {
- ($template = $period) =~ s/ //;
- $template = Utils::read_file( FixMyStreet->path_to( "templates/email/emptyhomes/" . $row->lang . "/questionnaire-$template.txt" )->stringify );
- } else {
- $template = FixMyStreet->get_email_template($cobrand->moniker, $row->lang, 'questionnaire.txt');
- }
-
- my %h = map { $_ => $row->$_ } qw/name title detail category/;
- $h{created} = Utils::prettify_duration( time() - $row->confirmed->epoch, 'week' );
-
- my $questionnaire = FixMyStreet::App->model('DB::Questionnaire')->create( {
- problem_id => $row->id,
- whensent => \'current_timestamp',
- } );
-
- # We won't send another questionnaire unless they ask for it (or it was
- # the first EHA questionnaire.
- $row->send_questionnaire( 0 )
- if $params->{site} ne 'emptyhomes' || $period eq '26 weeks';
-
- my $token = FixMyStreet::App->model("DB::Token")->new_result( {
- scope => 'questionnaire',
- data => $questionnaire->id,
- } );
- $h{url} = $cobrand->base_url($row->cobrand_data) . '/Q/' . $token->token;
-
- print "Sending questionnaire " . $questionnaire->id . ", problem "
- . $row->id . ", token " . $token->token . " to "
- . $row->user->email . "\n"
- if $params->{verbose};
-
- my $result = FixMyStreet::App->send_email_cron(
- {
- _template_ => $template,
- _parameters_ => \%h,
- To => [ [ $row->user->email, $row->name ] ],
- },
- undef,
- $params->{nomail},
- $cobrand
- );
- unless ($result) {
- print " ...success\n" if $params->{verbose};
- $row->update();
- $token->insert();
- } else {
- print " ...failed\n" if $params->{verbose};
- $questionnaire->delete;
- }
- }
+ require FixMyStreet::Script::Questionnaires;
+ FixMyStreet::Script::Questionnaires::send($params);
}
sub timeline {