aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/DB/ResultSet
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/DB/ResultSet')
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Alert.pm10
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/AlertType.pm266
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Comment.pm16
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Nearby.pm7
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Problem.pm315
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Questionnaire.pm104
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Secret.pm12
7 files changed, 47 insertions, 683 deletions
diff --git a/perllib/FixMyStreet/DB/ResultSet/Alert.pm b/perllib/FixMyStreet/DB/ResultSet/Alert.pm
index bb1c61141..c61053fff 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/ ];
@@ -35,6 +35,13 @@ sub timeline_disabled {
);
}
+# Return summary for alerts on reports (so excluding alerts on updates)
+sub summary_report_alerts {
+ my ( $rs, $restriction ) = @_;
+ $rs = $rs->search({ alert_type => { '!=', 'new_updates' } });
+ return $rs->summary_count($restriction);
+}
+
sub summary_count {
my ( $rs, $restriction ) = @_;
@@ -47,4 +54,5 @@ sub summary_count {
}
);
}
+
1;
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..9f254a018 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Comment.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Comment.pm
@@ -5,20 +5,20 @@ use strict;
use warnings;
sub to_body {
- my ($rs, $body_restriction) = @_;
- return FixMyStreet::DB::ResultSet::Problem::to_body($rs, $body_restriction);
+ my ($rs, $bodies) = @_;
+ return FixMyStreet::DB::ResultSet::Problem::to_body($rs, $bodies, 1);
}
sub timeline {
- my ( $rs, $body_restriction ) = @_;
+ my ( $rs ) = @_;
my $prefetch =
- FixMyStreet::App->model('DB')->schema->storage->sql_maker->quote_char ?
+ $rs->result_source->storage->sql_maker->quote_char ?
[ qw/user/ ] :
[];
- return $rs->to_body($body_restriction)->search(
+ return $rs->search(
{
state => 'confirmed',
created => { '>=', \"current_timestamp-'7 days'::interval" },
@@ -30,17 +30,13 @@ sub timeline {
}
sub summary_count {
- my ( $rs, $body_restriction ) = @_;
+ my ( $rs ) = @_;
my $params = {
group_by => ['me.state'],
select => [ 'me.state', { count => 'me.id' } ],
as => [qw/state state_count/],
};
- if ($body_restriction) {
- $rs = $rs->to_body($body_restriction);
- $params->{join} = 'problem';
- }
return $rs->search(undef, $params);
}
diff --git a/perllib/FixMyStreet/DB/ResultSet/Nearby.pm b/perllib/FixMyStreet/DB/ResultSet/Nearby.pm
index a6b00ef7b..9db1c6525 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Nearby.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Nearby.pm
@@ -4,6 +4,11 @@ use base 'DBIx::Class::ResultSet';
use strict;
use warnings;
+sub to_body {
+ my ($rs, $bodies) = @_;
+ return FixMyStreet::DB::ResultSet::Problem::to_body($rs, $bodies, 1);
+}
+
sub nearby {
my ( $rs, $c, $dist, $ids, $limit, $mid_lat, $mid_lon, $interval, $category, $states ) = @_;
@@ -21,7 +26,7 @@ sub nearby {
if $ids;
$params->{category} = $category if $category;
- $rs = FixMyStreet::DB::ResultSet::Problem::to_body($rs, $c->cobrand->body_restriction);
+ $rs = $c->cobrand->problems_restriction($rs);
my $attrs = {
prefetch => 'problem',
diff --git a/perllib/FixMyStreet/DB/ResultSet/Problem.pm b/perllib/FixMyStreet/DB/ResultSet/Problem.pm
index e9f5d0f8e..488030928 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;
@@ -21,13 +16,15 @@ sub set_restriction {
}
sub to_body {
- my ($rs, $bodies) = @_;
+ my ($rs, $bodies, $join) = @_;
return $rs unless $bodies;
unless (ref $bodies eq 'ARRAY') {
$bodies = [ map { ref $_ ? $_->id : $_ } $bodies ];
}
+ $join = { join => 'problem' } if $join;
$rs = $rs->search(
- \[ "regexp_split_to_array(bodies_str, ',') && ?", [ {} => $bodies ] ]
+ \[ "regexp_split_to_array(bodies_str, ',') && ?", [ {} => $bodies ] ],
+ $join
);
return $rs;
}
@@ -173,7 +170,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 +232,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 {
diff --git a/perllib/FixMyStreet/DB/ResultSet/Secret.pm b/perllib/FixMyStreet/DB/ResultSet/Secret.pm
new file mode 100644
index 000000000..971584b9a
--- /dev/null
+++ b/perllib/FixMyStreet/DB/ResultSet/Secret.pm
@@ -0,0 +1,12 @@
+package FixMyStreet::DB::ResultSet::Secret;
+use base 'DBIx::Class::ResultSet';
+
+use strict;
+use warnings;
+
+sub get {
+ my $rs = shift;
+ return $rs->first->secret;
+}
+
+1;