Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 53 additions & 6 deletions perllib/FYR/Queue.pm
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ use FYR::Cobrand;
our $message_calculated_values = "
length(message) as message_length,
(select count(*) from questionnaire_answer where questionnaire_answer.message_id = message.id
and question_id = 0 and answer = 'no') as questionnaire_0_no,
and question_id = 0 and answer in ('no', 'no_m')) as questionnaire_0_no,
(select count(*) from questionnaire_answer where questionnaire_answer.message_id = message.id
and question_id = 0 and answer = 'yes') as questionnaire_0_yes,
and question_id = 0 and answer in ('yes', 'yes_m')) as questionnaire_0_yes,
(select count(*) from questionnaire_answer where questionnaire_answer.message_id = message.id
and question_id = 1 and answer = 'no') as questionnaire_1_no,
(select count(*) from questionnaire_answer where questionnaire_answer.message_id = message.id
Expand Down Expand Up @@ -501,6 +501,16 @@ sub write_messages($$$$$;$$$$){
dbh()->rollback();
throw $E;
}finally{
# For group messages, mark all but the first message as no_questionnaire
# so only one survey is sent per multi-recipient batch
if (defined($group_id) && scalar(@$msgidlist) > 1) {
my @sorted_ids = sort @$msgidlist;
my $first_id = $sorted_ids[0];
foreach my $mid (@sorted_ids) {
next if $mid eq $first_id;
dbh()->do("update message set no_questionnaire = 't' where id = ?", {}, $mid);
}
}
dbh()->commit();
};

Expand Down Expand Up @@ -1447,13 +1457,16 @@ sub make_questionnaire_email ($;$) {
my $not_expected_url = $base_url . '/E/' . $token;
my $no_url = $base_url . '/N/' . $token;

my $is_multi = $msg->{group_id} ? 1 : 0;

my $settings = {
yes_url => $yes_url,
no_url => $no_url,
unsatisfactory_url => $unsatisfactory_url,
not_expected_url => $not_expected_url,
weeks_ago => $reminder ? _('Three') : _('Two'),
their_constituents => $msg->{recipient_type} eq 'HOC' ? 'the public' : 'their constituents'
their_constituents => $msg->{recipient_type} eq 'HOC' ? 'the public' : 'their constituents',
is_multi => $is_multi,
};
my $params;
try {
Expand Down Expand Up @@ -1489,11 +1502,18 @@ sub make_questionnaire_email ($;$) {

$text = build_text_email($text);

my $subject;
if ($is_multi) {
$subject = sprintf(_('Did any of your %s reply to your letter?'), $msg->{recipient_position_plural});
} else {
$subject = sprintf(_('Did your %s reply to your letter?'), $msg->{recipient_position});
}

return Email::MIME->create(
header_str => [
From => mySociety::Email::format_email_address(email_sender_name($msg->{cobrand}, $msg->{cocode}), do_not_reply_sender($msg->{cobrand})),
To => mySociety::Email::format_email_address($msg->{sender_name}, $msg->{sender_email}),
Subject => sprintf(_('Did your %s reply to your letter?'), $msg->{recipient_position}),
Subject => $subject,
Date => strftime('%a, %e %b %Y %H:%M:%S %z', localtime(FYR::DB::Time())),
'Message-ID' => email_message_id($msg->{id}),
],
Expand Down Expand Up @@ -1652,9 +1672,18 @@ sub record_questionnaire_answer ($$$) {
return $id;
}

# For multi-recipient messages, append _m suffix to distinguish
# responses about groups of representatives from single-rep responses
# this is deducable from the message but this prevents misinterpretation

my $stored_answer = $answer;
if ($msg->{group_id} && $qn == 0) {
$stored_answer = $answer . '_m';
}

# record response, replacing existing response to same question
dbh()->do('delete from questionnaire_answer where message_id = ? and question_id = ?', {}, $id, $qn);
dbh()->do('insert into questionnaire_answer (message_id, question_id, answer, whenanswered) values (?, ?, ?, ?)', {}, $id, $qn, $answer, time());
dbh()->do('insert into questionnaire_answer (message_id, question_id, answer, whenanswered) values (?, ?, ?, ?)', {}, $id, $qn, $stored_answer, time());
logmsg($id, 1, "answer of \"$answer\" received for questionnaire qn #$qn");
dbh()->commit();
return $id;
Expand All @@ -1676,6 +1705,23 @@ sub get_questionnaire_message ($) {
}
}

=item is_multi_questionnaire_message TOKEN

Return 1 if the questionnaire message associated with TOKEN is part of a
multi-recipient group, 0 otherwise.

=cut
sub is_multi_questionnaire_message ($) {
my ($token) = @_;
if (my $id = check_token("questionnaire", $token)) {
my $group_id = dbh()->selectrow_array(
"select group_id from message where id = ?", {}, $id
);
return $group_id ? 1 : 0;
}
return 0;
}

=item record_analysis_data MSGID MSG_SUMMARY ANALYSIS_DATA

Record a user's response to the post confirm questionnaire for some extra analysis data.
Expand Down Expand Up @@ -1967,7 +2013,8 @@ my %state_action = (
}
}
if ($msg->{no_questionnaire}) {
# don't send questionnaire for test messages
# don't send questionnaire for no_questionnaire messages
# (includes non-primary messages in a group)
$dosend = 0;
}

Expand Down
11 changes: 11 additions & 0 deletions phplib/queue.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,17 @@ function msg_get_questionnaire_message($token) {
return $result;
}

/* msg_is_multi_questionnaire_message TOKEN

Return 1 if the questionnaire message associated with TOKEN is part of a
multi-recipient group, 0 otherwise. */
function msg_is_multi_questionnaire_message($token) {
global $msg_client;
$params = func_get_args();
$result = $msg_client->call('FYR.Queue.is_multi_questionnaire_message', $params);
return $result;
}

/* msg_admin_recent_events COUNT [IMPORTANT]

Returns an array of hashes of information about the most recent COUNT
Expand Down
47 changes: 41 additions & 6 deletions script/create-test-survey
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Insert a dummy message row (if one doesn't already exist) and print
# survey test URLs using a valid questionnaire token.
#
# Usage: script/create-test-survey [--base-url URL]
# Usage: script/create-test-survey [--base-url URL] [--multi]
#

use strict;
Expand All @@ -23,9 +23,15 @@ use mySociety::DBHandle qw(dbh);
use FYR::Queue;

my $base_url = "http://localhost:8085";
GetOptions('base-url=s' => \$base_url) or die "Usage: $0 [--base-url URL]\n";
my $multi = 0;
GetOptions(
'base-url=s' => \$base_url,
'multi' => \$multi,
) or die "Usage: $0 [--base-url URL] [--multi]\n";

my $msg_id = "deadbeef01234567dead"; # fixed 20 hex-char ID so reruns are idempotent
my $msg_id = $multi ? "deadbeef01234567aaa1" : "deadbeef01234567dead";
my $msg_id_2 = "deadbeef01234567aaa2"; # second message for multi group
my $group_id = "abcdef0123456789abcd";
my $now = time();

# Only insert if the test message doesn't already exist (to preserve
Expand All @@ -39,24 +45,53 @@ if (!$existing) {
id, sender_name, sender_email, sender_addr, sender_postcode,
sender_ipaddr, recipient_id, recipient_name, recipient_type,
recipient_email,
message, state, created, confirmed, laststatechange
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
message, state, created, confirmed, laststatechange,
group_id
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
}, {},
$msg_id,
"Test User", "test\@example.com", "1 Test Street\nTestville", "SW1A 1AA",
"127.0.0.1", 1, "Test Representative", "WMC",
"test-rep\@example.com",
"This is a test message.", "finished", $now, $now, $now,
$multi ? $group_id : undef,
);

# For multi mode, create a second message in the same group
if ($multi) {
dbh()->do(q{
INSERT INTO message (
id, sender_name, sender_email, sender_addr, sender_postcode,
sender_ipaddr, recipient_id, recipient_name, recipient_type,
recipient_email,
message, state, created, confirmed, laststatechange,
group_id, no_questionnaire
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
}, {},
$msg_id_2,
"Test User", "test\@example.com", "1 Test Street\nTestville", "SW1A 1AA",
"127.0.0.1", 2, "Test Representative 2", "WMC",
"test-rep2\@example.com",
"This is a test message.", "finished", $now, $now, $now,
$group_id, 't',
);
}

dbh()->commit();
print "Created dummy message: $msg_id\n";
print "Created dummy " . ($multi ? "multi-recipient " : "") . "message: $msg_id\n";
if ($multi) {
print "Created second group message: $msg_id_2 (group: $group_id)\n";
}
} else {
print "Dummy message already exists: $msg_id\n";
}

my $token = FYR::Queue::make_token("questionnaire", $msg_id);

print "\nQuestionnaire token: $token\n";
if ($multi) {
print "Mode: MULTI (answers will be recorded with _m suffix)\n";
}
print "\nTest URLs (via /response -- records Q0 then redirects to /firsttime):\n\n";

my $sep = "+" . ("-" x 18) . "+" . ("-" x 80) . "+";
Expand Down
26 changes: 21 additions & 5 deletions templates/emails/questionnaire
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
<?=$values['weeks_ago']?> weeks ago we sent your letter to <?=$values['recipient_name']?>, your
<?=$values['recipient_position']?>. (For reference, there's a copy of your
<?=$values['weeks_ago']?> weeks ago we sent your letter to <?php if ($values['is_multi']) { ?>your <?=$values['recipient_position_plural']?><?php } else { ?><?=$values['recipient_name']?>, your
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are parsed by mySociety::Email.pm so only do simple substitution so php tags will be included verbatim. If you want to do this you'll either need a separate template for multi person messages or do the logic in the code.

<?=$values['recipient_position']?><?php } ?>. (For reference, there's a copy of your
letter at the bottom of this email.)

Please help us understand how well representatives are doing at
responding to their constituents.
responding to <?=$values['their_constituents']?>.

Did your <?=$values['recipient_position']?> reply to your message?
<?php if ($values['is_multi']) { ?>Did any of your <?=$values['recipient_position_plural']?> reply to your message?

YES, at least one replied! - please click here:
<?=$values['yes_url']?>

YES, but I don't think my question was answered! - please click here:
<?=$values['unsatisfactory_url']?>

YES, but it was only an acknowledgement! - please click here:
<?=$values['no_url']?>

NO, but I didn't expect/require a response! - please click here:
<?=$values['not_expected_url']?>

NO, none of them replied! - please click here:
<?=$values['no_url']?>
<?php } else { ?>Did your <?=$values['recipient_position']?> reply to your message?

YES, they replied! - please click here:
<?=$values['yes_url']?>
Expand All @@ -21,7 +37,7 @@ NO, but I didn't expect/require a response! - please click here:

NO, they did not reply! - please click here:
<?=$values['no_url']?>

<?php } ?>
Your feedback allows us to analyse the responsiveness of politicians in the UK.
We use this information to check that the service is working, alert us to
potential issues, and perform research into how responsive politicians
Expand Down
21 changes: 20 additions & 1 deletion templates/emails/questionnaire.html
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
<th style="<?= $values['td_style'] ?> <?= $values['primary_column_style'] ?>">

<?php if ($values['is_multi']) { ?>
<h1 style="<?= $values['h1_style'] ?>">Did any of your <?= $values['recipient_position_plural'] ?> reply to your message?</h1>
<p style="<?= $values['p_style'] ?>"><?= $values['weeks_ago'] ?> weeks ago, you used <a href="https://www.writetothem.com/">WriteToThem.com</a> to send a message to your <?= $values['recipient_position_plural'] ?>.</p>

<p style="<?= $values['p_style'] ?>">Did any of your <?= $values['recipient_position_plural'] ?> reply to your message?</p>
<?php } else { ?>
<h1 style="<?= $values['h1_style'] ?>">Has <?= $values['recipient_name'] ?> replied to your message?</h1>
<p style="<?= $values['p_style'] ?>"><?= $values['weeks_ago'] ?> weeks ago, you used <a href="https://www.writetothem.com/">WriteToThem.com</a> to send a message to <?= $values['recipient_name'] ?>.</p>

<p style="<?= $values['p_style'] ?>">Did <?= $values['recipient_name'] ?> reply to your message?</p>
<?php } ?>

<br>

<table <?= $values['table_reset'] ?> class="nofold" style="border-collapse: collapse;">
<tr>
<th style="<?= $values['questionnaire_option_td_style'] ?> width: 0%;"><?= $values['questionnaire_dot_good'] ?></th>
<th style="<?= $values['questionnaire_option_td_style'] ?>">
<?php if ($values['is_multi']) { ?>
<a style="display: block;" href="<?=$values['yes_url']?>"><strong>Yes</strong>, at least one replied</a>
<?php } else { ?>
<a style="display: block;" href="<?=$values['yes_url']?>"><strong>Yes</strong>, they replied</a>
<?php } ?>
</th>
</tr>
<tr>
Expand All @@ -35,14 +46,18 @@ <h1 style="<?= $values['h1_style'] ?>">Has <?= $values['recipient_name'] ?> repl
<tr>
<th style="<?= $values['questionnaire_option_td_style'] ?> width: 0%;"><?= $values['questionnaire_dot_bad'] ?></th>
<th style="<?= $values['questionnaire_option_td_style'] ?>">
<?php if ($values['is_multi']) { ?>
<a style="display: block;" href="<?=$values['no_url']?>"><strong>No</strong>, none of them replied</a>
<?php } else { ?>
<a style="display: block;" href="<?=$values['no_url']?>"><strong>No</strong>, they have not replied</a>
<?php } ?>
</th>
</tr>
</table>

<br>

<p style="<?= $values['p_style'] ?>">Your feedback allows us to analyse the responsiveness of politicians in the UK. We use this information to check that the service is working, alert us to potential issues, and perform research into how responsive politicians are to contact from constituents.</p>
<p style="<?= $values['p_style'] ?>">Your feedback allows us to analyse the responsiveness of politicians in the UK. We use this information to check that the service is working, alert us to potential issues, and perform research into how responsive politicians are to contact from <?= $values['their_constituents'] ?>.</p>

<p style="<?= $values['p_style'] ?>">A copy of your letter is below. <b>Note that we do not keep a copy of your letter on file, so please keep this email for your records.</b></p>

Expand All @@ -53,6 +68,10 @@ <h1 style="<?= $values['h1_style'] ?>">Has <?= $values['recipient_name'] ?> repl
</tr><tr>

<th style="<?= $values['td_style'] ?> <?= $values['secondary_column_style'] ?>">
<?php if ($values['is_multi']) { ?>
<h2 style="<?= $values['h2_style'] ?>">Your letter to your <?= $values['recipient_position_plural'] ?></h2>
<?php } else { ?>
<h2 style="<?= $values['h2_style'] ?>">Your letter to <?= $values['recipient_name'] ?></h2>
<?php } ?>
<?= $values['email_text'] ?>
</th>
15 changes: 12 additions & 3 deletions templates/website/service-questions.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,21 @@ <h2><?= _('A few more questions') ?></h2>

<?php
$response = isset($values['response']) ? $values['response'] : '';
$is_multi = !empty($values['is_multi']);
if ($response === 'yes') {
echo '<p>' . _('Great &mdash; we&rsquo;re glad your representative replied!') . '</p>';
if ($is_multi) {
echo '<p>' . _('Great &mdash; we&rsquo;re glad at least one of your representatives replied!') . '</p>';
} else {
echo '<p>' . _('Great &mdash; we&rsquo;re glad your representative replied!') . '</p>';
}
} elseif ($response === 'unsatisfactory') {
echo '<p>' . _('Sorry to hear your question wasn&rsquo;t fully answered.') . '</p>';
} elseif ($response === 'no') {
echo '<p>' . _('We hope your representative gets back to you soon.') . '</p>';
if ($is_multi) {
echo '<p>' . _('We hope your representatives get back to you soon.') . '</p>';
} else {
echo '<p>' . _('We hope your representative gets back to you soon.') . '</p>';
}
} elseif ($response === 'not_expected') {
echo '<p>' . _('Thanks for letting us know.') . '</p>';
}
Expand All @@ -41,7 +50,7 @@ <h2><?= _('A few more questions') ?></h2>
<input type="hidden" name="submitted" value="1">

<fieldset class="survey-fieldset survey-fieldset--separated">
<legend><strong><?= _('Is this the first time you&rsquo;ve ever contacted one of your elected representatives?') ?></strong></legend>
<legend><strong><?php if ($is_multi) { ?><?= _('Is this the first time you&rsquo;ve ever contacted your elected representatives?') ?><?php } else { ?><?= _('Is this the first time you&rsquo;ve ever contacted one of your elected representatives?') ?><?php } ?></strong></legend>
<label><input type="radio" name="answer" value="yes" required> <?= _('Yes, this is the first time') ?></label>
<label><input type="radio" name="answer" value="no"> <?= _('No, I&rsquo;ve done it before') ?></label>
</fieldset>
Expand Down
7 changes: 7 additions & 0 deletions web/firsttime.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,17 @@
$service_questions = array_slice($service_question_pool, 0, 2);
sort($service_questions);

// Check if this is a multi-recipient message
$is_multi = false;
if (!$preview) {
$is_multi = msg_is_multi_questionnaire_message($token) ? true : false;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you not do msg_is_multi_questionnaire_message($token) == 1 here to be explicit and also skip the ternary?

}

$values = array(
'token' => $token,
'response' => get_http_var('response'),
'service_questions' => $service_questions,
'is_multi' => $is_multi,
'cobrand' => $cobrand,
'cocode' => $cocode,
'host' => fyr_get_host(),
Expand Down
3 changes: 3 additions & 0 deletions web/services/queue.cgi
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ while ($req->Accept() >= 0) {
'FYR.Queue.admin_update_recipient' => sub {
return FYR::Queue::admin_update_recipient($_[0], $_[1], $_[2]);
},
'FYR.Queue.is_multi_questionnaire_message' => sub {
return FYR::Queue::is_multi_questionnaire_message($_[0]);
},
);
$W->exit_if_changed();
last if $exit_requested;
Expand Down
4 changes: 2 additions & 2 deletions web/write.php
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,8 @@ function submitFaxes() {

if ($grpid) {

// No questionnaire for group mails
$no_questionnaire = true;
// Questionnaire will be sent once per group (for the first message)
$no_questionnaire = false;

// check the group id
if (!preg_match("/^[0-9a-f]{20}$/i", $grpid)) {
Expand Down
Loading