1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
package FixMyStreet::Script::Questionnaires;
use strict;
use warnings;
use Utils;
use FixMyStreet::DB;
use FixMyStreet::Email;
use FixMyStreet::Map;
use FixMyStreet::Cobrand;
sub send {
my ( $params ) = @_;
send_questionnaires_period( '4 weeks', $params );
}
sub send_questionnaires_period {
my ( $period, $params ) = @_;
# Don't send if we don't have a fixed state
return unless FixMyStreet::DB::Result::Problem::fixed_states->{fixed};
my $rs = FixMyStreet::DB->resultset('Questionnaire');
# 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,
};
$q_params->{'-or'} = [
\'(select max(whensent) from questionnaire where me.id=problem_id) IS NULL',
\"(select max(whenanswered) from questionnaire where me.id=problem_id) < current_timestamp - '$period'::interval",
];
my $unsent = FixMyStreet::DB->resultset('Problem')->search( $q_params, {
order_by => { -desc => 'confirmed' }
} );
while (my $row = $unsent->next) {
my $cobrand = $row->get_cobrand_logged;
$cobrand->set_lang_and_domain($row->lang, 1);
FixMyStreet::Map::set_map_class($cobrand->map_type);
# Not all cobrands send questionnaires
next unless $cobrand->send_questionnaires;
# Cobrands can also override sending per row if they wish
my $cobrand_send = $cobrand->call_hook('send_questionnaire', $row) // 1;
if ($row->is_from_abuser || !$row->user->email_verified ||
!$cobrand_send || $row->is_closed
) {
$row->update( { send_questionnaire => 0 } );
next;
}
# 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 %h = map { $_ => $row->$_ } qw/name title detail category/;
$h{report} = $row;
$h{created} = Utils::prettify_duration( time() - $row->confirmed->epoch, 'week' );
my $questionnaire = $rs->create( {
problem_id => $row->id,
whensent => \'current_timestamp',
} );
# We won't send another questionnaire unless they ask for it
$row->send_questionnaire( 0 );
my $token = FixMyStreet::DB->resultset("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::Email::send_cron(
$rs->result_source->schema,
'questionnaire.txt',
\%h,
{
To => [ [ $row->user->email, $row->name ] ],
},
undef,
$params->{nomail},
$cobrand,
$row->lang,
);
unless ($result) {
print " ...success\n" if $params->{verbose};
$row->update();
$token->insert();
} else {
print " ...failed\n" if $params->{verbose};
$questionnaire->delete;
}
}
}
1;
|