aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Arter <davea@mysociety.org>2016-08-01 12:03:45 +0100
committerDave Arter <davea@mysociety.org>2016-08-01 12:03:45 +0100
commit1af9684e54aedb7f9935cdc4d38a28c61ec7d1f5 (patch)
treed6b044f54e070f8dbf265083534e849eb9ad6ead
parent14aaf6fafaa9aa8736f49851e95fa2c3c566c056 (diff)
parent27e0c74321f48f9997745bf00647e3958f34d8e2 (diff)
Merge branch '1281-html-emails'
-rw-r--r--perllib/FixMyStreet/App.pm40
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm1
-rw-r--r--perllib/FixMyStreet/App/Controller/Contact.pm20
-rw-r--r--perllib/FixMyStreet/App/Controller/Photo.pm1
-rw-r--r--perllib/FixMyStreet/App/Controller/Report.pm11
-rw-r--r--perllib/FixMyStreet/App/Model/PhotoSet.pm14
-rw-r--r--perllib/FixMyStreet/App/View/Email.pm7
-rw-r--r--perllib/FixMyStreet/Cobrand/Default.pm2
-rw-r--r--perllib/FixMyStreet/DB/Result/Comment.pm23
-rw-r--r--perllib/FixMyStreet/DB/Result/Problem.pm102
-rw-r--r--perllib/FixMyStreet/Email.pm126
-rw-r--r--perllib/FixMyStreet/Map.pm5
-rw-r--r--perllib/FixMyStreet/Map/OSM.pm31
-rw-r--r--perllib/FixMyStreet/Roles/PhotoSet.pm35
-rw-r--r--perllib/FixMyStreet/Script/Alerts.pm89
-rw-r--r--perllib/FixMyStreet/Script/Questionnaires.pm3
-rw-r--r--perllib/FixMyStreet/Script/Reports.pm3
-rw-r--r--perllib/FixMyStreet/SendReport/Email.pm1
-rw-r--r--perllib/FixMyStreet/TestMech.pm42
-rw-r--r--t/app/controller/alert_new.t75
-rw-r--r--t/app/controller/auth.t19
-rw-r--r--t/app/controller/auth_social.t12
-rw-r--r--t/app/controller/contact.t8
-rw-r--r--t/app/controller/moderate.t3
-rw-r--r--t/app/controller/questionnaire.t28
-rw-r--r--t/app/controller/report_import.t15
-rw-r--r--t/app/controller/report_new.t38
-rw-r--r--t/app/controller/report_updates.t27
-rw-r--r--t/app/helpers/emails/html_test.html15
-rw-r--r--t/app/helpers/emails/html_test.txt14
-rw-r--r--t/app/helpers/emails/test.txt (renamed from templates/email/default/test.txt)0
-rw-r--r--t/app/helpers/send_email.t32
-rw-r--r--t/app/model/alert_type.t18
-rw-r--r--t/app/model/problem.t27
-rw-r--r--t/cobrand/bromley.t7
-rw-r--r--t/cobrand/fixamingata.t11
-rw-r--r--templates/email/bromley/_email_color_overrides.html19
-rw-r--r--templates/email/bromley/questionnaire.txt8
-rw-r--r--templates/email/default/_email_bottom.html17
-rw-r--r--templates/email/default/_email_comment_list.html14
-rw-r--r--templates/email/default/_email_comment_list.txt8
-rw-r--r--templates/email/default/_email_report_list.html19
-rw-r--r--templates/email/default/_email_report_list.txt8
-rw-r--r--templates/email/default/_email_settings.html108
-rw-r--r--templates/email/default/_email_top.html64
-rw-r--r--templates/email/default/alert-confirm.html21
-rw-r--r--templates/email/default/alert-problem-area.html19
-rw-r--r--templates/email/default/alert-problem-area.txt2
-rw-r--r--templates/email/default/alert-problem-council.html19
-rw-r--r--templates/email/default/alert-problem-council.txt2
-rw-r--r--templates/email/default/alert-problem-nearby.html19
-rw-r--r--templates/email/default/alert-problem-nearby.txt2
-rw-r--r--templates/email/default/alert-problem-ward.html19
-rw-r--r--templates/email/default/alert-problem-ward.txt2
-rw-r--r--templates/email/default/alert-problem.html19
-rw-r--r--templates/email/default/alert-problem.txt2
-rw-r--r--templates/email/default/alert-update.html31
-rw-r--r--templates/email/default/alert-update.txt3
-rw-r--r--templates/email/default/change_email.html22
-rw-r--r--templates/email/default/change_email.txt4
-rw-r--r--templates/email/default/contact.html45
-rw-r--r--templates/email/default/contact.txt4
-rw-r--r--templates/email/default/login.html22
-rw-r--r--templates/email/default/login.txt4
-rw-r--r--templates/email/default/problem-confirm-not-sending.html36
-rw-r--r--templates/email/default/problem-confirm-not-sending.txt7
-rw-r--r--templates/email/default/problem-confirm.html39
-rw-r--r--templates/email/default/problem-confirm.txt6
-rw-r--r--templates/email/default/problem-moderated.html38
-rw-r--r--templates/email/default/problem-moderated.txt7
-rw-r--r--templates/email/default/questionnaire.html36
-rw-r--r--templates/email/default/questionnaire.txt8
-rw-r--r--templates/email/default/submit.html63
-rw-r--r--templates/email/default/update-confirm-donotsend.txt2
-rw-r--r--templates/email/default/update-confirm.html33
-rw-r--r--templates/email/fiksgatami/alert-problem-area.txt2
-rw-r--r--templates/email/fiksgatami/alert-problem-council.txt2
-rw-r--r--templates/email/fiksgatami/alert-problem-nearby.txt2
-rw-r--r--templates/email/fiksgatami/alert-problem-ward.txt2
-rw-r--r--templates/email/fiksgatami/alert-problem.txt2
-rw-r--r--templates/email/fiksgatami/alert-update.txt2
-rw-r--r--templates/email/fiksgatami/contact.txt4
-rw-r--r--templates/email/fiksgatami/nn/alert-problem-area.txt2
-rw-r--r--templates/email/fiksgatami/nn/alert-problem-council.txt2
-rw-r--r--templates/email/fiksgatami/nn/alert-problem-nearby.txt2
-rw-r--r--templates/email/fiksgatami/nn/alert-problem-ward.txt2
-rw-r--r--templates/email/fiksgatami/nn/alert-problem.txt2
-rw-r--r--templates/email/fiksgatami/nn/alert-update.txt2
-rw-r--r--templates/email/fiksgatami/questionnaire.txt6
-rw-r--r--templates/email/fixamingata/alert-problem-area.txt2
-rw-r--r--templates/email/fixamingata/alert-problem-council.txt2
-rw-r--r--templates/email/fixamingata/alert-problem-nearby.txt2
-rw-r--r--templates/email/fixamingata/alert-problem-ward.txt2
-rw-r--r--templates/email/fixamingata/alert-problem.txt2
-rw-r--r--templates/email/fixamingata/alert-update.txt2
-rw-r--r--templates/email/fixamingata/contact.txt4
-rw-r--r--templates/email/fixamingata/questionnaire.txt8
-rw-r--r--templates/email/fixmystreet.com/_submit_footer.html9
-rw-r--r--templates/email/fixmystreet.com/submit-oxfordshire.txt47
-rw-r--r--templates/email/fixmystreet.com/submit.html69
-rw-r--r--templates/email/fixmystreet.com/submit.txt4
-rw-r--r--templates/email/fixmystreet.com/update-confirm-donotsend.txt4
-rw-r--r--templates/email/greenwich/_email_color_overrides.html20
-rw-r--r--templates/email/greenwich/_email_setting_overrides.html5
-rw-r--r--templates/email/harrogate/submit.txt47
-rw-r--r--templates/email/oxfordshire/_email_color_overrides.html17
-rw-r--r--templates/email/oxfordshire/submit.txt47
-rw-r--r--templates/email/warwickshire/_email_color_overrides.html17
-rw-r--r--templates/email/zurich/alert-moderation-overdue.txt2
-rw-r--r--templates/email/zurich/alert-overdue.txt2
-rw-r--r--templates/email/zurich/alert-update.txt2
-rw-r--r--web/cobrands/bromley/images/email-logo.gifbin0 -> 3030 bytes
-rw-r--r--web/cobrands/fixmystreet.com/images/email-logo.gifbin0 -> 2521 bytes
-rw-r--r--web/cobrands/greenwich/images/email-logo.gifbin0 -> 3637 bytes
-rw-r--r--web/cobrands/oxfordshire/images/email-logo.gifbin0 -> 4708 bytes
-rw-r--r--web/cobrands/warwickshire/images/email-logo.gifbin0 -> 3573 bytes
116 files changed, 1562 insertions, 494 deletions
diff --git a/perllib/FixMyStreet/App.pm b/perllib/FixMyStreet/App.pm
index be0e91101..ea7d43512 100644
--- a/perllib/FixMyStreet/App.pm
+++ b/perllib/FixMyStreet/App.pm
@@ -306,30 +306,38 @@ sub send_email {
my $sender_name = $c->cobrand->contact_name;
# create the vars to pass to the email template
+ my @include_path = @{ $c->cobrand->path_to_email_templates($c->stash->{lang_code}) };
my $vars = {
from => [ $sender, _($sender_name) ],
%{ $c->stash },
%$extra_stash_values,
- additional_template_paths => $c->cobrand->path_to_email_templates($c->stash->{lang_code}),
+ additional_template_paths => \@include_path,
};
return if FixMyStreet::Email::is_abuser($c->model('DB')->schema, $vars->{to});
- my $email = mySociety::Locale::in_gb_locale { FixMyStreet::Email::construct_email(
- {
- _body_ => $c->view('Email')->render( $c, $template, $vars ),
- _attachments_ => $extra_stash_values->{attachments},
- From => $vars->{from},
- To => $vars->{to},
- 'Message-ID' => sprintf('<fms-%s-%s@%s>',
- time(), unpack('h*', random_bytes(5, 1)), $c->config->{EMAIL_DOMAIN}
- ),
- $vars->{subject} ? (Subject => $vars->{subject}) : (),
- $vars->{'Reply-To'} ? ('Reply-To' => $vars->{'Reply-To'}) : (),
- }
- ) };
-
- # send the email
+ my @inline_images;
+ $vars->{inline_image} = sub { FixMyStreet::Email::add_inline_image(\@inline_images, @_); },
+
+ my $html_template = FixMyStreet::Email::get_html_template($template, @include_path);
+ my $html_compiled = eval {
+ $c->view('Email')->render($c, $html_template, $vars) if $html_template;
+ };
+ $c->log->debug("Error compiling HTML $template: $@") if $@;
+
+ my $data = {
+ _body_ => $c->view('Email')->render( $c, $template, $vars ),
+ _attachments_ => $extra_stash_values->{attachments},
+ From => $vars->{from},
+ To => $vars->{to},
+ 'Message-ID' => FixMyStreet::Email::message_id(),
+ };
+ $data->{Subject} = $vars->{subject} if $vars->{subject};
+ $data->{'Reply-To'} = $vars->{'Reply-To'} if $vars->{'Reply-To'};
+ $data->{_html_} = $html_compiled if $html_compiled;
+ $data->{_html_images_} = \@inline_images if @inline_images;
+
+ my $email = mySociety::Locale::in_gb_locale { FixMyStreet::Email::construct_email($data) };
$c->model('EmailSend')->send($email);
return $email;
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index 93e8f4b22..44a653d62 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -8,7 +8,6 @@ use Path::Class;
use POSIX qw(strftime strcoll);
use Digest::SHA qw(sha1_hex);
use mySociety::EmailUtil qw(is_valid_email);
-use if !$ENV{TRAVIS}, 'Image::Magick';
use DateTime::Format::Strptime;
use List::Util 'first';
diff --git a/perllib/FixMyStreet/App/Controller/Contact.pm b/perllib/FixMyStreet/App/Controller/Contact.pm
index e20011471..5527256a6 100644
--- a/perllib/FixMyStreet/App/Controller/Contact.pm
+++ b/perllib/FixMyStreet/App/Controller/Contact.pm
@@ -168,26 +168,22 @@ sub prepare_params_for_email : Private {
if ( $c->stash->{update} ) {
- my $problem_url = $base_url . '/report/' . $c->stash->{update}->problem_id
+ $c->stash->{problem_url} = $base_url . '/report/' . $c->stash->{update}->problem_id
. '#update_' . $c->stash->{update}->id;
- my $admin_url = " - $admin_url" . '/update_edit/' . $c->stash->{update}->id
- if $admin_url;
- $c->stash->{message} .= sprintf(
- " \n\n[ Complaint about update %d on report %d - %s%s ]",
+ $c->stash->{admin_url} = $admin_url . '/update_edit/' . $c->stash->{update}->id;
+ $c->stash->{complaint} = sprintf(
+ "Complaint about update %d on report %d",
$c->stash->{update}->id,
$c->stash->{update}->problem_id,
- $problem_url, $admin_url
);
}
elsif ( $c->stash->{problem} ) {
- my $problem_url = $base_url . '/report/' . $c->stash->{problem}->id;
- $admin_url = " - $admin_url" . '/report_edit/' . $c->stash->{problem}->id
- if $admin_url;
- $c->stash->{message} .= sprintf(
- " \n\n[ Complaint about report %d - %s%s ]",
+ $c->stash->{problem_url} = $base_url . '/report/' . $c->stash->{problem}->id;
+ $c->stash->{admin_url} = $admin_url . '/report_edit/' . $c->stash->{problem}->id;
+ $c->stash->{complaint} = sprintf(
+ "Complaint about report %d",
$c->stash->{problem}->id,
- $problem_url, $admin_url
);
# flag this so it's automatically listed in the admin interface
diff --git a/perllib/FixMyStreet/App/Controller/Photo.pm b/perllib/FixMyStreet/App/Controller/Photo.pm
index 2734491fa..2302322bf 100644
--- a/perllib/FixMyStreet/App/Controller/Photo.pm
+++ b/perllib/FixMyStreet/App/Controller/Photo.pm
@@ -8,7 +8,6 @@ use JSON::MaybeXS;
use File::Path;
use File::Slurp;
use FixMyStreet::App::Model::PhotoSet;
-use if !$ENV{TRAVIS}, 'Image::Magick';
=head1 NAME
diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm
index 89df4a52d..6ac3c8ea1 100644
--- a/perllib/FixMyStreet/App/Controller/Report.pm
+++ b/perllib/FixMyStreet/App/Controller/Report.pm
@@ -278,6 +278,17 @@ sub delete :Local :Args(1) {
return $c->res->redirect($uri);
}
+sub map : Path('') : Args(2) {
+ my ( $self, $c, $id, $map ) = @_;
+
+ $c->detach( '/page_error_404_not_found', [] ) unless $map eq 'map';
+ $c->forward( 'load_problem_or_display_error', [ $id ] );
+
+ my $image = $c->stash->{problem}->static_map;
+ $c->res->content_type($image->{content_type});
+ $c->res->body($image->{data});
+}
+
__PACKAGE__->meta->make_immutable;
1;
diff --git a/perllib/FixMyStreet/App/Model/PhotoSet.pm b/perllib/FixMyStreet/App/Model/PhotoSet.pm
index 1c8a86e3a..487786a3b 100644
--- a/perllib/FixMyStreet/App/Model/PhotoSet.pm
+++ b/perllib/FixMyStreet/App/Model/PhotoSet.pm
@@ -4,7 +4,13 @@ package FixMyStreet::App::Model::PhotoSet;
use Moose;
use Path::Tiny 'path';
-use if !$ENV{TRAVIS}, 'Image::Magick';
+
+my $IM = eval {
+ require Image::Magick;
+ Image::Magick->import;
+ 1;
+};
+
use Scalar::Util 'openhandle', 'blessed';
use Digest::SHA qw(sha1_hex);
use Image::Size;
@@ -318,7 +324,7 @@ sub rotate_image {
sub _rotate_image {
my ($photo, $direction) = @_;
- return $photo unless $Image::Magick::VERSION;
+ return $photo unless $IM;
my $image = Image::Magick->new;
$image->BlobToImage($photo);
my $err = $image->Rotate($direction);
@@ -332,7 +338,7 @@ sub _rotate_image {
# Shrinks a picture to the specified size, but keeping in proportion.
sub _shrink {
my ($photo, $size) = @_;
- return $photo unless $Image::Magick::VERSION;
+ return $photo unless $IM;
my $image = Image::Magick->new;
$image->BlobToImage($photo);
my $err = $image->Scale(geometry => "$size>");
@@ -346,7 +352,7 @@ sub _shrink {
# Shrinks a picture to 90x60, cropping so that it is exactly that.
sub _crop {
my ($photo) = @_;
- return $photo unless $Image::Magick::VERSION;
+ return $photo unless $IM;
my $image = Image::Magick->new;
$image->BlobToImage($photo);
my $err = $image->Resize( geometry => "90x60^" );
diff --git a/perllib/FixMyStreet/App/View/Email.pm b/perllib/FixMyStreet/App/View/Email.pm
index 86d5c1d60..6073ee814 100644
--- a/perllib/FixMyStreet/App/View/Email.pm
+++ b/perllib/FixMyStreet/App/View/Email.pm
@@ -14,7 +14,7 @@ __PACKAGE__->config(
],
ENCODING => 'utf8',
render_die => 1,
- expose_methods => ['loc'],
+ expose_methods => ['loc', 'file_exists'],
);
=head1 NAME
@@ -40,5 +40,10 @@ sub loc {
return _(@args);
}
+sub file_exists {
+ my ( $self, $c, @args ) = @_;
+ -e FixMyStreet->path_to(@args);
+}
+
1;
diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm
index e5ec0c13a..686684a05 100644
--- a/perllib/FixMyStreet/Cobrand/Default.pm
+++ b/perllib/FixMyStreet/Cobrand/Default.pm
@@ -395,7 +395,7 @@ Return an override type of map if necessary.
=cut
sub map_type {
my $self = shift;
- return 'OSM' if $self->{c}->req->uri->host =~ /^osm\./;
+ return 'OSM' if $self->{c} && $self->{c}->req->uri->host =~ /^osm\./;
return;
}
diff --git a/perllib/FixMyStreet/DB/Result/Comment.pm b/perllib/FixMyStreet/DB/Result/Comment.pm
index 85cdb29f0..25798edca 100644
--- a/perllib/FixMyStreet/DB/Result/Comment.pm
+++ b/perllib/FixMyStreet/DB/Result/Comment.pm
@@ -99,7 +99,8 @@ __PACKAGE__->rabx_column('extra');
use Moo;
use namespace::clean -except => [ 'meta' ];
-with 'FixMyStreet::Roles::Abuser';
+with 'FixMyStreet::Roles::Abuser',
+ 'FixMyStreet::Roles::PhotoSet';
my $stz = sub {
my ( $orig, $self ) = ( shift, shift );
@@ -147,26 +148,6 @@ sub confirm {
$self->confirmed( \'current_timestamp' );
}
-=head2 get_photoset
-
-Return a PhotoSet object for all photos attached to this field
-
- my $photoset = $obj->get_photoset;
- print $photoset->num_images;
- return $photoset->get_image_data(num => 0, size => 'full');
-
-=cut
-
-sub get_photoset {
- my ($self) = @_;
- my $class = 'FixMyStreet::App::Model::PhotoSet';
- eval "use $class";
- return $class->new({
- db_data => $self->photo,
- object => $self,
- });
-}
-
sub photos {
my $self = shift;
my $photoset = $self->get_photoset;
diff --git a/perllib/FixMyStreet/DB/Result/Problem.pm b/perllib/FixMyStreet/DB/Result/Problem.pm
index 2599f24ae..92865ace9 100644
--- a/perllib/FixMyStreet/DB/Result/Problem.pm
+++ b/perllib/FixMyStreet/DB/Result/Problem.pm
@@ -161,9 +161,17 @@ use Moo;
use namespace::clean -except => [ 'meta' ];
use Utils;
use FixMyStreet::Map::FMS;
+use LWP::Simple qw($ua);
+
+my $IM = eval {
+ require Image::Magick;
+ Image::Magick->import;
+ 1;
+};
with 'FixMyStreet::Roles::Abuser',
- 'FixMyStreet::Roles::Extra';
+ 'FixMyStreet::Roles::Extra',
+ 'FixMyStreet::Roles::PhotoSet';
=head2
@@ -653,7 +661,7 @@ sub can_display_external_id {
if ($self->external_id && $self->send_method_used && $self->bodies_str =~ /(2237|2550)/) {
return 1;
}
- return 0;
+ return 0;
}
sub duration_string {
@@ -809,26 +817,6 @@ sub latest_moderation_log_entry {
return $self->admin_log_entries->search({ action => 'moderation' }, { order_by => 'id desc' })->first;
}
-=head2 get_photoset
-
-Return a PhotoSet object for all photos attached to this field
-
- my $photoset = $obj->get_photoset;
- print $photoset->num_images;
- return $photoset->get_image_data(num => 0, size => 'full');
-
-=cut
-
-sub get_photoset {
- my ($self) = @_;
- my $class = 'FixMyStreet::App::Model::PhotoSet';
- eval "use $class";
- return $class->new({
- db_data => $self->photo,
- object => $self,
- });
-}
-
sub photos {
my $self = shift;
my $photoset = $self->get_photoset;
@@ -855,7 +843,7 @@ __PACKAGE__->has_many(
"admin_log_entries",
"FixMyStreet::DB::Result::AdminLog",
{ "foreign.object_id" => "self.id" },
- {
+ {
cascade_copy => 0, cascade_delete => 0,
where => { 'object_type' => 'problem' },
}
@@ -892,6 +880,7 @@ has get_cobrand_logged => (
},
);
+
sub pin_data {
my ($self, $c, $page, %opts) = @_;
my $colour = $c->cobrand->pin_colour($self, $page);
@@ -904,6 +893,73 @@ sub pin_data {
title => $opts{private} ? $self->title : $self->title_safe,
problem => $self,
}
+};
+
+sub static_map {
+ my ($self) = @_;
+
+ return unless $IM;
+
+ my $orig_map_class = FixMyStreet::Map::set_map_class('OSM')
+ unless $FixMyStreet::Map::map_class->isa("FixMyStreet::Map::OSM");
+
+ my $map_data = $FixMyStreet::Map::map_class->generate_map_data(
+ { cobrand => $self->get_cobrand_logged },
+ latitude => $self->latitude,
+ longitude => $self->longitude,
+ pins => $self->used_map
+ ? [ {
+ latitude => $self->latitude,
+ longitude => $self->longitude,
+ colour => $self->get_cobrand_logged->pin_colour($self, 'report'),
+ type => 'big',
+ } ]
+ : [],
+ );
+
+ $ua->agent("FixMyStreet/1.0");
+ my $image;
+ for (my $i=0; $i<4; $i++) {
+ my $tile_url = $map_data->{tiles}->[$i];
+ if ($tile_url =~ m{^//}) {
+ $tile_url = "https:$tile_url";
+ }
+ my $tile = LWP::Simple::get($tile_url);
+ my $im = Image::Magick->new;
+ $im->BlobToImage($tile);
+ if (!$image) {
+ $image = $im;
+ $image->Extent(geometry => '512x512', gravity => 'NorthWest');
+ } else {
+ my $gravity = ($i<2?'North':'South') . ($i%2?'East':'West');
+ $image->Composite(image => $im, gravity => $gravity);
+ }
+ }
+
+ # The only pin might be the report pin, with added x/y
+ my $pin = $map_data->{pins}->[0];
+ if ($pin) {
+ my $im = Image::Magick->new;
+ $im->read(FixMyStreet->path_to('web', 'i', 'pin-yellow.png'));
+ $image->Composite(image => $im, gravity => 'NorthWest',
+ x => $pin->{px} - 24, y => $pin->{py} - 64);
+ }
+
+ # Bottom 128/ top 64 pixels will never have a pin
+ $image->Extent( geometry => '512x384', gravity => 'NorthWest');
+ $image->Extent( geometry => '512x320', gravity => 'SouthWest');
+
+ $image->Scale( geometry => "310x200>" );
+
+ my @blobs = $image->ImageToBlob(magick => 'jpeg');
+ undef $image;
+
+ FixMyStreet::Map::set_map_class($orig_map_class) if $orig_map_class;
+
+ return {
+ data => $blobs[0],
+ content_type => 'image/jpeg',
+ };
}
1;
diff --git a/perllib/FixMyStreet/Email.pm b/perllib/FixMyStreet/Email.pm
index d955f6f72..34ac1514c 100644
--- a/perllib/FixMyStreet/Email.pm
+++ b/perllib/FixMyStreet/Email.pm
@@ -8,6 +8,7 @@ package FixMyStreet::Email;
use Email::MIME;
use Encode;
+use File::Spec;
use POSIX qw();
use Template;
use Digest::HMAC_SHA1 qw(hmac_sha1_hex);
@@ -72,10 +73,77 @@ sub is_abuser {
sub _render_template {
my ($tt, $template, $vars, %options) = @_;
my $var;
- $tt->process($template, $vars, \$var);
+ $tt->process($template, $vars, \$var) || print "Template processing error: " . $tt->error() . "\n";
return $var;
}
+sub _unique_id {
+ sprintf('fms-%s-%s@%s',
+ time(), unpack('h*', random_bytes(5, 1)),
+ FixMyStreet->config('EMAIL_DOMAIN'));
+}
+
+sub message_id {
+ '<' . _unique_id() . '>'
+}
+
+sub add_inline_image {
+ my ($inline_images, $obj, $name) = @_;
+ if (ref $obj eq 'HASH') {
+ return _add_inline($inline_images, $name, $obj->{data}, $obj->{content_type});
+ } else {
+ my $file = FixMyStreet->path_to($obj);
+ return _add_inline($inline_images, $file->basename, scalar $file->slurp);
+ }
+}
+
+sub _add_inline {
+ my ($inline_images, $name, $data, $type) = @_;
+
+ return unless $data;
+
+ $name ||= 'photo';
+ if ($type) {
+ if ($name !~ /\./) {
+ my ($suffix) = $type =~ m{image/(.*)};
+ $name .= ".$suffix";
+ }
+ } else {
+ my ($b, $t) = split /\./, $name;
+ $type = "image/$t";
+ }
+
+ my $cid = _unique_id();
+ push @$inline_images, {
+ body => $data,
+ attributes => {
+ id => $cid,
+ filename => $name,
+ content_type => $type,
+ encoding => 'base64',
+ name => $name,
+ },
+ };
+ return "cid:$cid";
+}
+
+# We only want an HTML template from the same directory as the .txt
+sub get_html_template {
+ my ($template, @include_path) = @_;
+ push @include_path, FixMyStreet->path_to( 'templates', 'email', 'default' );
+ (my $html_template = $template) =~ s/\.txt$/\.html/;
+ my $template_dir = find_template_dir($template, @include_path);
+ my $html_template_dir = find_template_dir($html_template, @include_path);
+ return $html_template if $template_dir eq $html_template_dir;
+}
+
+sub find_template_dir {
+ my ($template, @include_path) = @_;
+ foreach (@include_path) {
+ return $_ if -e File::Spec->catfile($_, $template);
+ }
+}
+
sub send_cron {
my ( $schema, $template, $vars, $hdrs, $env_from, $nomail, $cobrand, $lang_code ) = @_;
@@ -88,11 +156,11 @@ sub send_cron {
return 1 if is_abuser($schema, $hdrs->{To});
- $hdrs->{'Message-ID'} = sprintf('<fms-cron-%s-%s@%s>', time(),
- unpack('h*', random_bytes(5, 1)), FixMyStreet->config('EMAIL_DOMAIN')
- );
+ $hdrs->{'Message-ID'} = message_id();
my @include_path = @{ $cobrand->path_to_email_templates($lang_code) };
+ my $html_template = get_html_template($template, @include_path);
+
push @include_path, FixMyStreet->path_to( 'templates', 'email', 'default' );
my $tt = Template->new({
ENCODING => 'utf8',
@@ -102,6 +170,14 @@ sub send_cron {
$vars->{site_name} = Utils::trim_text(_render_template($tt, 'site-name.txt', $vars));
$hdrs->{_body_} = _render_template($tt, $template, $vars);
+ if ($html_template) {
+ my @inline_images;
+ $vars->{inline_image} = sub { add_inline_image(\@inline_images, @_) };
+ $vars->{file_exists} = sub { -e FixMyStreet->path_to(@_) };
+ $hdrs->{_html_} = _render_template($tt, $html_template, $vars);
+ $hdrs->{_html_images_} = \@inline_images;
+ }
+
my $email = mySociety::Locale::in_gb_locale { construct_email($hdrs) };
if ($nomail) {
@@ -236,6 +312,47 @@ sub construct_email ($) {
),
];
+ my $overall_type;
+ if ($p->{_html_}) {
+ my $html = _mime_create(
+ body_str => $p->{_html_},
+ attributes => {
+ charset => 'utf-8',
+ encoding => 'quoted-printable',
+ content_type => 'text/html',
+ },
+ );
+ if ($p->{_html_images_} || $p->{_attachments_}) {
+ $parts = [ _mime_create(
+ attributes => { content_type => 'multipart/alternative' },
+ parts => [ $parts->[0], $html ]
+ ) ];
+ } else {
+ # The top level will be the alternative multipart if there are
+ # no images and no other attachments
+ push @$parts, $html;
+ $overall_type = 'multipart/alternative';
+ }
+ if ($p->{_html_images_}) {
+ foreach (@{$p->{_html_images_}}) {
+ my $cid = delete $_->{attributes}->{id};
+ my $part = _mime_create(%$_);
+ $part->header_set('Content-ID' => "<$cid>");
+ push @$parts, $part;
+ }
+ if ($p->{_attachments_}) {
+ $parts = [ _mime_create(
+ attributes => { content_type => 'multipart/related' },
+ parts => $parts,
+ ) ];
+ } else {
+ # The top level will be the related multipart if there are
+ # images but no other attachments
+ $overall_type = 'multipart/related';
+ }
+ }
+ }
+
if ($p->{_attachments_}) {
push @$parts, map { _mime_create(%$_) } @{$p->{_attachments_}};
}
@@ -245,6 +362,7 @@ sub construct_email ($) {
parts => $parts,
attributes => {
charset => 'utf-8',
+ $overall_type ? (content_type => $overall_type) : (),
},
);
diff --git a/perllib/FixMyStreet/Map.pm b/perllib/FixMyStreet/Map.pm
index 355fd8666..a850492b9 100644
--- a/perllib/FixMyStreet/Map.pm
+++ b/perllib/FixMyStreet/Map.pm
@@ -47,7 +47,8 @@ sub reload_allowed_maps {
=head2 map_class
-Set and return the appropriate class given a query parameter string.
+Sets the appropriate class given a query parameter string.
+Returns the old map class, if any.
=cut
@@ -57,7 +58,9 @@ sub set_map_class {
$str = __PACKAGE__.'::'.$str if $str;
my %avail = map { $_ => 1 } @ALL_MAP_CLASSES;
$str = $ALL_MAP_CLASSES[0] unless $str && $avail{$str};
+ my $old_map_class = $map_class;
$map_class = $str;
+ return $old_map_class;
}
sub display_map {
diff --git a/perllib/FixMyStreet/Map/OSM.pm b/perllib/FixMyStreet/Map/OSM.pm
index ae9e73a0a..d4000f1a4 100644
--- a/perllib/FixMyStreet/Map/OSM.pm
+++ b/perllib/FixMyStreet/Map/OSM.pm
@@ -50,6 +50,23 @@ sub copyright {
sub display_map {
my ($self, $c, %params) = @_;
+ # Map centre may be overridden in the query string
+ $params{latitude} = Utils::truncate_coordinate($c->get_param('lat') + 0)
+ if defined $c->get_param('lat');
+ $params{longitude} = Utils::truncate_coordinate($c->get_param('lon') + 0)
+ if defined $c->get_param('lon');
+
+ my %data;
+ $data{cobrand} = $c->cobrand;
+ $data{distance} = $c->stash->{distance};
+ $data{zoom} = $c->get_param('zoom') + 0 if defined $c->get_param('zoom');
+
+ $c->stash->{map} = $self->generate_map_data(\%data, %params);
+}
+
+sub generate_map_data {
+ my ($self, $data, %params) = @_;
+
my $numZoomLevels = ZOOM_LEVELS;
my $zoomOffset = MIN_ZOOM_LEVEL;
if ($params{any_zoom}) {
@@ -58,18 +75,12 @@ sub display_map {
}
# Adjust zoom level dependent upon population density
- my $dist = $c->stash->{distance}
+ my $dist = $data->{distance}
|| FixMyStreet::Gaze::get_radius_containing_population( $params{latitude}, $params{longitude} );
- my $default_zoom = $c->cobrand->default_map_zoom() ? $c->cobrand->default_map_zoom() : $numZoomLevels - 4;
+ my $default_zoom = $data->{cobrand}->default_map_zoom() || ($numZoomLevels - 4);
$default_zoom = $numZoomLevels - 3 if $dist < 10;
- # Map centre may be overridden in the query string
- $params{latitude} = Utils::truncate_coordinate($c->get_param('lat') + 0)
- if defined $c->get_param('lat');
- $params{longitude} = Utils::truncate_coordinate($c->get_param('lon') + 0)
- if defined $c->get_param('lon');
-
- my $zoom = defined $c->get_param('zoom') ? $c->get_param('zoom') + 0 : $default_zoom;
+ my $zoom = $data->{zoom} || $default_zoom;
$zoom = $numZoomLevels - 1 if $zoom >= $numZoomLevels;
$zoom = 0 if $zoom < 0;
$params{zoom_act} = $zoomOffset + $zoom;
@@ -79,7 +90,7 @@ sub display_map {
($pin->{px}, $pin->{py}) = latlon_to_px($pin->{latitude}, $pin->{longitude}, $params{x_tile}, $params{y_tile}, $params{zoom_act});
}
- $c->stash->{map} = {
+ return {
%params,
type => $self->map_template(),
map_type => $self->map_type(),
diff --git a/perllib/FixMyStreet/Roles/PhotoSet.pm b/perllib/FixMyStreet/Roles/PhotoSet.pm
new file mode 100644
index 000000000..9607b5049
--- /dev/null
+++ b/perllib/FixMyStreet/Roles/PhotoSet.pm
@@ -0,0 +1,35 @@
+package FixMyStreet::Roles::PhotoSet;
+use Moo::Role;
+
+=head1 NAME
+
+FixMyStreet::Roles::Photoset - role for accessing photosets
+
+=cut
+
+=head2 get_photoset
+
+Return a PhotoSet object for all photos attached to this field
+
+ my $photoset = $obj->get_photoset;
+ print $photoset->num_images;
+ return $photoset->get_image_data(num => 0, size => 'full');
+
+=cut
+
+sub get_photoset {
+ my ($self) = @_;
+ my $class = 'FixMyStreet::App::Model::PhotoSet';
+ eval "use $class";
+ return $class->new({
+ db_data => $self->photo,
+ object => $self,
+ });
+}
+
+sub get_first_image_fp {
+ my ($self) = @_;
+ return $self->get_photoset->get_image_data( num => 0, size => 'fp' );
+}
+
+1;
diff --git a/perllib/FixMyStreet/Script/Alerts.pm b/perllib/FixMyStreet/Script/Alerts.pm
index 062601044..91f5cd6ef 100644
--- a/perllib/FixMyStreet/Script/Alerts.pm
+++ b/perllib/FixMyStreet/Script/Alerts.pm
@@ -15,9 +15,13 @@ use RABX;
use FixMyStreet::Cobrand;
use FixMyStreet::DB;
use FixMyStreet::Email;
+use FixMyStreet::Map;
+use FixMyStreet::App::Model::PhotoSet;
FixMyStreet->configure_mysociety_dbhandle;
+my $parser = DateTime::Format::Pg->new();
+
# 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
@@ -37,6 +41,7 @@ sub send() {
$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,
+ $item_table.photo as item_photo,
$head_table.*
from alert, $item_table, $head_table
where alert.parameter::integer = $head_table.id
@@ -63,7 +68,7 @@ sub send() {
$query = dbh()->prepare($query);
$query->execute();
my $last_alert_id;
- my %data = ( template => $alert_type->template, data => '', schema => $schema );
+ my %data = ( template => $alert_type->template, data => [], schema => $schema );
while (my $row = $query->fetchrow_hashref) {
my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->{alert_cobrand})->new();
@@ -84,7 +89,7 @@ sub send() {
} );
if ($last_alert_id && $last_alert_id != $row->{alert_id}) {
_send_aggregated_alert_email(%data);
- %data = ( template => $alert_type->template, data => '', schema => $schema );
+ %data = ( template => $alert_type->template, data => [], schema => $schema );
}
# create problem status message for the templates
@@ -116,30 +121,50 @@ sub send() {
} 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";
+
+ 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);
+ $row->{confirmed} = $dt;
+
+ # Hack in the image for the non-object updates
+ $row->{get_first_image_fp} = sub {
+ return FixMyStreet::App::Model::PhotoSet->new({
+ db_data => $row->{item_photo},
+ })->get_image_data( num => 0, size => 'fp' );
+ };
+
# 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;
+ $row->{nearest} = $nearest_st;
}
- $data{data} .= "\n\n------\n\n";
+
+ my $dt = $parser->parse_timestamp( $row->{confirmed} );
+ FixMyStreet->set_time_zone($dt);
+ $row->{confirmed} = $dt;
+
+ # Hack in the image for the non-object reports
+ $row->{get_first_image_fp} = sub {
+ return FixMyStreet::App::Model::PhotoSet->new({
+ db_data => $row->{photo},
+ })->get_image_data( num => 0, size => 'fp' );
+ };
}
+
+ push @{$data{data}}, $row;
+
if (!$data{alert_user_id}) {
%data = (%data, %$row);
+ if ($ref eq 'new_updates') {
+ # Get a report object for its photo and static map
+ $data{report} = $schema->resultset('Problem')->find({ id => $row->{id} });
+ }
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};
@@ -149,7 +174,7 @@ sub send() {
$data{ward_name} = $va_info->{name};
}
}
- $data{cobrand} = $row->{alert_cobrand};
+ $data{cobrand} = $cobrand;
$data{cobrand_data} = $row->{alert_cobrand_data};
$data{lang} = $row->{alert_lang};
$last_alert_id = $row->{alert_id};
@@ -183,15 +208,16 @@ sub send() {
my $states = "'" . join( "', '", FixMyStreet::DB::Result::Problem::visible_states() ) . "'";
my %data = (
template => $template,
- data => '',
+ data => [],
alert_id => $alert->id,
alert_email => $alert->user->email,
lang => $alert->lang,
- cobrand => $alert->cobrand,
+ cobrand => $cobrand,
cobrand_data => $alert->cobrand_data,
schema => $schema,
);
- my $q = "select problem.id, problem.bodies_str, problem.postcode, problem.geocode, problem.title from problem_find_nearby(?, ?, ?) as nearby, problem, users
+ my $q = "select problem.id, problem.bodies_str, problem.postcode, problem.geocode, problem.confirmed,
+ problem.title, problem.detail, problem.photo 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)
@@ -207,24 +233,31 @@ sub send() {
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;
+ $row->{nearest} = $nearest_st;
}
- $data{data} .= "\n\n------\n\n";
+ my $dt = $parser->parse_timestamp( $row->{confirmed} );
+ FixMyStreet->set_time_zone($dt);
+ $row->{confirmed} = $dt;
+ $row->{get_first_image_fp} = sub {
+ return FixMyStreet::App::Model::PhotoSet->new({
+ db_data => $row->{photo},
+ })->get_image_data( num => 0, size => 'fp' );
+ };
+ push @{$data{data}}, $row;
}
- _send_aggregated_alert_email(%data) if $data{data};
+ _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();
+ my $cobrand = $data{cobrand};
$cobrand->set_lang_and_domain( $data{lang}, 1, FixMyStreet->path_to('locale')->stringify );
+ FixMyStreet::Map::set_map_class($cobrand->map_type);
if (!$data{alert_email}) {
my $user = $data{schema}->resultset('User')->find( {
diff --git a/perllib/FixMyStreet/Script/Questionnaires.pm b/perllib/FixMyStreet/Script/Questionnaires.pm
index c5bc6bfe0..3f22eb150 100644
--- a/perllib/FixMyStreet/Script/Questionnaires.pm
+++ b/perllib/FixMyStreet/Script/Questionnaires.pm
@@ -5,6 +5,7 @@ use warnings;
use Utils;
use FixMyStreet::DB;
use FixMyStreet::Email;
+use FixMyStreet::Map;
use FixMyStreet::Cobrand;
sub send {
@@ -41,6 +42,7 @@ sub send_questionnaires_period {
my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($row->cobrand)->new();
$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;
@@ -53,6 +55,7 @@ sub send_questionnaires_period {
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( {
diff --git a/perllib/FixMyStreet/Script/Reports.pm b/perllib/FixMyStreet/Script/Reports.pm
index 30d24f640..311d8fec4 100644
--- a/perllib/FixMyStreet/Script/Reports.pm
+++ b/perllib/FixMyStreet/Script/Reports.pm
@@ -14,6 +14,7 @@ use FixMyStreet;
use FixMyStreet::Cobrand;
use FixMyStreet::DB;
use FixMyStreet::Email;
+use FixMyStreet::Map;
use FixMyStreet::SendReport;
sub send(;$) {
@@ -60,6 +61,7 @@ sub send(;$) {
}
$cobrand->set_lang_and_domain($row->lang, 1);
+ FixMyStreet::Map::set_map_class($cobrand->map_type);
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;
@@ -73,6 +75,7 @@ sub send(;$) {
# 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/;
+ $h{report} = $row;
map { $h{$_} = $row->user->$_ || '' } qw/email phone/;
$h{confirmed} = DateTime::Format::Pg->format_datetime( $row->confirmed->truncate (to => 'second' ) )
if $row->confirmed;
diff --git a/perllib/FixMyStreet/SendReport/Email.pm b/perllib/FixMyStreet/SendReport/Email.pm
index 8582ebb3b..2eab1c754 100644
--- a/perllib/FixMyStreet/SendReport/Email.pm
+++ b/perllib/FixMyStreet/SendReport/Email.pm
@@ -52,7 +52,6 @@ sub build_recipient_list {
sub get_template {
my ( $self, $row ) = @_;
- return 'submit-oxfordshire.txt' if $row->cobrand eq 'fixmystreet' && $row->bodies_str eq 2237;
return 'submit.txt';
}
diff --git a/perllib/FixMyStreet/TestMech.pm b/perllib/FixMyStreet/TestMech.pm
index 937780a31..5f4a6ceed 100644
--- a/perllib/FixMyStreet/TestMech.pm
+++ b/perllib/FixMyStreet/TestMech.pm
@@ -221,6 +221,48 @@ sub get_email {
return $emails[0];
}
+sub get_text_body_from_email {
+ my ($mech, $email, $obj) = @_;
+ unless ($email) {
+ $email = $mech->get_email;
+ $mech->clear_emails_ok;
+ }
+
+ my $body;
+ $email->walk_parts(sub {
+ my $part = shift;
+ return if $part->subparts;
+ return if $part->content_type !~ m{text/plain};
+ $body = $obj ? $part : $part->body;
+ ok $body, "Found text body";
+ });
+ return $body;
+}
+
+sub get_link_from_email {
+ my ($mech, $email, $multiple) = @_;
+ unless ($email) {
+ $email = $mech->get_email;
+ $mech->clear_emails_ok;
+ }
+
+ my @links;
+ $email->walk_parts(sub {
+ my $part = shift;
+ return if $part->subparts;
+ return if $part->content_type !~ m{text/};
+ if (@links) {
+ # Must be an HTML part now, first two links are in header
+ my @html_links = $part->body =~ m{https?://[^"]+}g;
+ is $links[0], $html_links[2], 'HTML link matches text link';
+ } else {
+ @links = $part->body =~ m{https?://\S+}g;
+ ok @links, "Found links in email '@links'";
+ }
+ });
+ return $multiple ? @links : $links[0];
+}
+
=head2 get_first_email
$email = $mech->get_first_email(@emails);
diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t
index 2c20daf9d..1b85adf7e 100644
--- a/t/app/controller/alert_new.t
+++ b/t/app/controller/alert_new.t
@@ -98,9 +98,10 @@ foreach my $test (
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/$test->{email_text}/i, "Correct email text";
+ like $mech->get_text_body_from_email($email), qr/$test->{email_text}/i, "Correct email text";
- my ( $url, $url_token ) = $email->body =~ m{(http://\S+/A/)(\S+)};
+ my $url = $mech->get_link_from_email($email);
+ my ($url_token) = $url =~ m{/A/(\S+)};
ok $url, "extracted confirm url '$url'";
my $token = FixMyStreet::App->model('DB::Token')->find(
@@ -119,10 +120,8 @@ foreach my $test (
$mech->get_ok( $test->{uri} . "&token=$csrf" );
- $email = $mech->get_email;
- ok $email, 'got a second email';
-
- ($url_token) = $email->body =~ m{http://\S+/A/(\S+)};
+ $url = $mech->get_link_from_email;
+ ($url_token) = $url =~ m{/A/(\S+)};
ok $url_token ne $existing_token, 'sent out a new token';
$token = FixMyStreet::App->model('DB::Token')->find(
@@ -361,9 +360,9 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
} );
};
if ( $alert->{email_confirm} ) {
- my $email = $mech->get_email;
+ my $url = $mech->get_link_from_email;
+ my ($url_token) = $url =~ m{/A/(\S+)};
$mech->clear_emails_ok;
- my ( $url, $url_token ) = $email->body =~ m{http://\S+(/A/(\S+))};
my $token = FixMyStreet::App->model('DB::Token')->find( { token => $url_token, scope => 'alert' } );
$mech->get_ok( $url );
$mech->content_contains('alert created');
@@ -446,30 +445,32 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
my @emails = $mech->get_email;
my $count;
for (@emails) {
- $count++ if $_->body =~ /The following updates have been left on this report:/;
- $count++ if $_->body =~ /The following new FixMyStreet reports have been added in the City of\s+Edinburgh\s+Council area:/;
- $count++ if $_->body =~ /The following FixMyStreet reports have been made within the area you\s+specified:/;
- $count++ if $_->body =~ /\s+-\s+Testing/;
+ my $body = $mech->get_text_body_from_email($_);
+ $count++ if $body =~ /The following updates have been left on this report:/;
+ $count++ if $body =~ /The following new FixMyStreet reports have been added in the City of\s+Edinburgh\s+Council area:/;
+ $count++ if $body =~ /The following FixMyStreet reports have been made within the area you\s+specified:/;
+ $count++ if $body =~ /\s+-\s+Testing/;
}
is $count, 5, 'Three emails, with five matching lines in them';
my $email = $emails[0];
- like $email->body, qr/Other User/, 'Update name given';
- unlike $email->body, qr/Anonymous User/, 'Update name not given';
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/Other User/, 'Update name given';
+ unlike $body, qr/Anonymous User/, 'Update name not given';
# The update alert was to the problem reporter, so has a special update URL
$mech->log_out_ok;
$mech->get_ok( "/report/$report_id" );
$mech->content_lacks( 'has not been fixed' );
- my ($url) = $email->body =~ m{(http://\S+/R/\S+)};
- ok $url, "extracted update url '$url'";
- $mech->get_ok( $url );
+ my @urls = $mech->get_link_from_email($email, 1);
+ ok $urls[0] =~ m{/R/\S+}, "extracted update url '$urls[0]'";
+ $mech->get_ok( $urls[0] );
is $mech->uri->path, "/report/" . $report_id, "redirected to report page";
$mech->content_contains( 'has not been fixed' );
$mech->not_logged_in_ok;
- ($url) = $emails[0]->body =~ m{http://\S+(/A/\S+)};
- $mech->get_ok( $url );
+ ok $urls[-1] =~ m{/A/\S+}, "unsubscribe URL '$urls[-1]'";
+ $mech->get_ok( $urls[-1] );
$mech->content_contains('alert deleted');
$mech->not_logged_in_ok;
@@ -546,13 +547,10 @@ subtest "Test signature template is used from cobrand" => sub {
}, sub {
FixMyStreet::App->model('DB::AlertType')->email_alerts();
};
- # TODO Note the below will fail if the db has an existing alert that matches
- $mech->email_count_is(1);
- my @emails = $mech->get_email;
- my $email = $emails[0];
- like $email->body, qr/All the best/, 'default signature used';
- unlike $email->body, qr/twitter.com/, 'nothing from fixmystreet signature';
+ my $email = $mech->get_text_body_from_email;
+ like $email, qr/All the best/, 'default signature used';
+ unlike $email, qr/twitter.com/, 'nothing from fixmystreet signature';
$update = FixMyStreet::App->model('DB::Comment')->create( {
problem_id => $report_id,
@@ -577,12 +575,9 @@ subtest "Test signature template is used from cobrand" => sub {
}, sub {
FixMyStreet::App->model('DB::AlertType')->email_alerts();
};
- # TODO Note the below will fail if the db has an existing alert that matches
- $mech->email_count_is(1);
- @emails = $mech->get_email;
- $email = $emails[0];
- like $email->body, qr/twitter.com/, 'fixmystreet signature used';
+ $email = $mech->get_text_body_from_email;
+ like $email, qr/twitter.com/, 'fixmystreet signature used';
$mech->delete_user($user1);
$mech->delete_user($user2);
@@ -682,9 +677,8 @@ for my $test (
}, sub {
FixMyStreet::App->model('DB::AlertType')->email_alerts();
};
- $mech->email_count_is(1);
- my $email = $mech->get_email;
- like $email->body, qr/Alert\s+test\s+for\s+non\s+public\s+reports/, 'alert contains public report';
+ my $email = $mech->get_text_body_from_email;
+ like $email, qr/Alert\s+test\s+for\s+non\s+public\s+reports/, 'alert contains public report';
$mech->delete_user( $user1 );
$mech->delete_user( $user2 );
@@ -766,16 +760,14 @@ subtest 'check new updates alerts for non public reports only go to report owner
ok $alert_user2, "alert created";
FixMyStreet::App->model('DB::AlertType')->email_alerts();
- $mech->email_count_is(1);
- my $email = $mech->get_email;
- like $email->body, qr/This is some more update text/, 'alert contains update text';
+ my $email = $mech->get_text_body_from_email;
+ like $email, qr/This is some more update text/, 'alert contains update text';
$mech->clear_emails_ok;
$report->update( { non_public => 0 } );
FixMyStreet::App->model('DB::AlertType')->email_alerts();
- $mech->email_count_is(1);
- $email = $mech->get_email;
- like $email->body, qr/This is some more update text/, 'alert contains update text';
+ $email = $mech->get_text_body_from_email;
+ like $email, qr/This is some more update text/, 'alert contains update text';
$mech->delete_user( $user1 );
$mech->delete_user( $user2 );
@@ -848,7 +840,6 @@ subtest 'check setting inlude dates in new updates cobrand option' => sub {
$mech->clear_emails_ok;
FixMyStreet::App->model('DB::AlertType')->email_alerts();
- $mech->email_count_is(1);
# if we don't do this then we're applying the date inflation code and
# it's timezone munging to the DateTime object above and not the DateTime
@@ -858,8 +849,8 @@ subtest 'check setting inlude dates in new updates cobrand option' => sub {
$update->discard_changes();
my $date_in_alert = Utils::prettify_dt( $update->confirmed );
- my $email = $mech->get_email;
- like $email->body, qr/$date_in_alert/, 'alert contains date';
+ my $email = $mech->get_text_body_from_email;
+ like $email, qr/$date_in_alert/, 'alert contains date';
$mech->delete_user( $user1 );
$mech->delete_user( $user2 );
diff --git a/t/app/controller/auth.t b/t/app/controller/auth.t
index 60f22acfb..251aa2977 100644
--- a/t/app/controller/auth.t
+++ b/t/app/controller/auth.t
@@ -72,8 +72,7 @@ $mech->not_logged_in_ok;
is $email->header('To'), $test_email, "to is correct";
# extract the link
- my ($link) = $email->body =~ m{(http://\S+)};
- ok $link, "Found a link in email '$link'";
+ my $link = $mech->get_link_from_email($email);
# check that the user does not exist
sub get_user {
@@ -117,9 +116,7 @@ $mech->not_logged_in_ok;
# follow link and change password - check not prompted for old password
$mech->not_logged_in_ok;
- my $email = $mech->get_email;
- $mech->clear_emails_ok;
- my ($link) = $email->body =~ m{(http://\S+)};
+ my $link = $mech->get_link_from_email;
$mech->get_ok($link);
is $mech->uri->path, '/faq', "redirected to the Help page";
@@ -187,9 +184,7 @@ subtest "Test change email page" => sub {
$mech->submit_form_ok({ with_fields => { email => $test_email2 } }, "change_email to $test_email2");
is $mech->uri->path, '/auth/change_email', "still on change email page";
$mech->content_contains( 'Now check your email', "found check your email" );
- my $email = $mech->get_email;
- $mech->clear_emails_ok;
- my ($link) = $email->body =~ m{(http://\S+)};
+ my $link = $mech->get_link_from_email;
$mech->get_ok($link);
is $mech->uri->path, '/auth/change_email/success', "redirected to the change_email page";
$mech->content_contains('successfully confirmed');
@@ -201,9 +196,7 @@ subtest "Test change email page" => sub {
);
is $mech->uri->path, '/auth/change_email', "still on change email page";
$mech->content_contains( 'Now check your email', "found check your email" );
- $email = $mech->get_email;
- $mech->clear_emails_ok;
- ($link) = $email->body =~ m{(http://\S+)};
+ $link = $mech->get_link_from_email;
$mech->get_ok($link);
is $mech->uri->path, '/auth/change_email/success', "redirected to the change_email page";
$mech->content_contains('successfully confirmed');
@@ -214,9 +207,7 @@ subtest "Test change email page" => sub {
);
is $mech->uri->path, '/auth/change_email', "still on change email page";
$mech->content_contains( 'Now check your email', "found check your email" );
- $email = $mech->get_email;
- $mech->clear_emails_ok;
- ($link) = $email->body =~ m{(http://\S+)};
+ $link = $mech->get_link_from_email;
$mech->log_out_ok;
$mech->get_ok($link);
isnt $mech->uri->path, '/auth/change_email/success', "not redirected to the change_email page";
diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t
index 6929c0ddc..f3eae32a7 100644
--- a/t/app/controller/auth_social.t
+++ b/t/app/controller/auth_social.t
@@ -113,10 +113,8 @@ for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) {
$mech->submit_form(with_fields => $fields);
$mech->content_contains('Nearly done! Now check your email');
- my $email = $mech->get_email;
- ok $email, "got an email";
+ my $url = $mech->get_link_from_email;
$mech->clear_emails_ok;
- my ( $url, $url_token ) = $email->body =~ m{(https?://\S+/[CMP]/)(\S+)};
ok $url, "extracted confirm url '$url'";
my $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $fb_email } );
@@ -125,7 +123,7 @@ for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) {
} else {
is $user->facebook_id, undef, 'User has no facebook ID';
}
- $mech->get_ok( $url . $url_token );
+ $mech->get_ok( $url );
$user = FixMyStreet::App->model( 'DB::User' )->find( { email => $fb_email } );
is $user->facebook_id, $fb_uid, 'User now has correct facebook ID';
@@ -225,10 +223,8 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) {
$mech->submit_form(with_fields => $fields);
$mech->content_contains('Nearly done! Now check your email');
- my $email = $mech->get_email;
- ok $email, "got an email";
+ my $url = $mech->get_link_from_email;
$mech->clear_emails_ok;
- my ( $url, $url_token ) = $email->body =~ m{(https?://\S+/[CMP]/)(\S+)};
ok $url, "extracted confirm url '$url'";
my $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $tw_email } );
@@ -237,7 +233,7 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) {
} else {
is $user->twitter_id, undef, 'User has no twitter ID';
}
- $mech->get_ok( $url . $url_token );
+ $mech->get_ok( $url );
$user = FixMyStreet::App->model( 'DB::User' )->find( { email => $tw_email } );
is $user->twitter_id, $tw_uid, 'User now has correct twitter ID';
diff --git a/t/app/controller/contact.t b/t/app/controller/contact.t
index 1b0f09a85..dd94fc431 100644
--- a/t/app/controller/contact.t
+++ b/t/app/controller/contact.t
@@ -251,16 +251,16 @@ for my $test (
}
$mech->submit_form_ok( { with_fields => $test->{fields} } );
$mech->content_contains('Thank you for your feedback');
- $mech->email_count_is(1);
my $email = $mech->get_email;
is $email->header('Subject'), 'FMS message: ' . $test->{fields}->{subject}, 'subject';
is $email->header('From'), "\"$test->{fields}->{name}\" <$test->{fields}->{em}>", 'from';
- like $email->body, qr/$test->{fields}->{message}/, 'body';
- like $email->body, qr/Sent by contact.cgi on \S+. IP address (?:\d{1,3}\.){3,}\d{1,3}/, 'body footer';
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/$test->{fields}->{message}/, 'body';
+ like $body, qr/Sent by contact.cgi on \S+. IP address (?:\d{1,3}\.){3,}\d{1,3}/, 'body footer';
my $problem_id = $test->{fields}{id};
- like $email->body, qr/Complaint about report $problem_id/, 'reporting a report'
+ like $body, qr/Complaint about report $problem_id/, 'reporting a report'
if $test->{fields}{id};
$problem_main->discard_changes;
diff --git a/t/app/controller/moderate.t b/t/app/controller/moderate.t
index 14c751115..e3e8bf2cf 100644
--- a/t/app/controller/moderate.t
+++ b/t/app/controller/moderate.t
@@ -169,8 +169,7 @@ subtest 'Problem moderation' => sub {
$report->discard_changes;
is $report->state, 'hidden', 'Is hidden';
- my $email = $mech->get_email;
- my ($url) = $email->body =~ m{(http://\S+)};
+ my $url = $mech->get_link_from_email;
ok $url, "extracted complain url '$url'";
$mech->get_ok($url);
diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t
index 7a46e48bd..b05f74225 100644
--- a/t/app/controller/questionnaire.t
+++ b/t/app/controller/questionnaire.t
@@ -58,12 +58,14 @@ FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires( {
} );
my $email = $mech->get_email;
ok $email, "got an email";
-like $email->body, qr/fill in our short questionnaire/i, "got questionnaire email";
+my $plain = $mech->get_text_body_from_email($email, 1);
+like $plain->body, qr/fill in our short questionnaire/i, "got questionnaire email";
-like $email->body_str, qr/Testing \x{2013} Detail/, 'email contains encoded character';
-is $email->header('Content-Type'), 'text/plain; charset="utf-8"', 'in the right character set';
+like $plain->body_str, qr/Testing \x{2013} Detail/, 'email contains encoded character';
+is $plain->header('Content-Type'), 'text/plain; charset="utf-8"', 'in the right character set';
-my ($token) = $email->body =~ m{http://.*?/Q/(\S+)};
+my $url = $mech->get_link_from_email($email);
+my ($token) = $url =~ m{/Q/(\S+)};
ok $token, "extracted questionnaire token '$token'";
$mech->clear_emails_ok;
@@ -399,13 +401,14 @@ FixMyStreet::override_config {
$questionnaire->delete;
FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires();
- $email = $mech->get_email;
- ok $email, "got an email";
- $mech->clear_emails_ok;
- (my $body = $email->body) =~ s/\s+/ /g;
+ my $email = $mech->get_email;
+ my $body = $mech->get_text_body_from_email($email);
+ $mech->clear_emails_ok;
+ $body =~ s/\s+/ /g;
like $body, qr/fill in our short questionnaire/i, "got questionnaire email";
- ($token) = $email->body =~ m{http://.*?/Q/(\S+)};
+ my $url = $mech->get_link_from_email($email);
+ ($token) = $url =~ m{/Q/(\S+)};
ok $token, "extracted questionnaire token '$token'";
# Test already answered the ever reported question, so not shown again
@@ -445,9 +448,10 @@ FixMyStreet::override_config {
ok $email, "got an email";
$mech->clear_emails_ok;
- like $email->body_str, qr/Testing \x{2013} Detail/, 'email contains encoded character from user';
- like $email->body_str, qr/sak p\xe5 FiksGataMi/, 'email contains encoded character from template';
- is $email->header('Content-Type'), 'text/plain; charset="utf-8"', 'email is in right encoding';
+ my $plain = $mech->get_text_body_from_email($email, 1);
+ like $plain->body_str, qr/Testing \x{2013} Detail/, 'email contains encoded character from user';
+ like $plain->body_str, qr/sak p\xe5 FiksGataMi/, 'email contains encoded character from template';
+ is $plain->header('Content-Type'), 'text/plain; charset="utf-8"', 'email is in right encoding';
};
$mech->delete_user('test@example.com');
diff --git a/t/app/controller/report_import.t b/t/app/controller/report_import.t
index 26acf7790..c8cbcf412 100644
--- a/t/app/controller/report_import.t
+++ b/t/app/controller/report_import.t
@@ -114,11 +114,8 @@ subtest "Submit a correct entry" => sub {
is $mech->content, 'SUCCESS', "Got success response";
# check that we have received the email
- $mech->email_count_is(1);
- my $email = $mech->get_email;
+ my $token_url = $mech->get_link_from_email;
$mech->clear_emails_ok;
-
- my ($token_url) = $email->body =~ m{(http://\S+)};
ok $token_url, "Found a token url $token_url";
# go to the token url
@@ -257,11 +254,8 @@ subtest "Submit a correct entry (with location)" => sub {
is $mech->content, 'SUCCESS', "Got success response";
# check that we have received the email
- $mech->email_count_is(1);
- my $email = $mech->get_email;
+ my $token_url = $mech->get_link_from_email;
$mech->clear_emails_ok;
-
- my ($token_url) = $email->body =~ m{(http://\S+)};
ok $token_url, "Found a token url $token_url";
# go to the token url
@@ -356,11 +350,8 @@ subtest "Submit a correct entry (with location) to cobrand" => sub {
is $mech->content, 'SUCCESS', "Got success response";
# check that we have received the email
- $mech->email_count_is(1);
- my $email = $mech->get_email;
+ my $token_url = $mech->get_link_from_email;
$mech->clear_emails_ok;
-
- my ($token_url) = $email->body =~ m{(http://\S+)};
ok $token_url, "Found a token url $token_url";
# go to the token url
diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t
index 2aebfa00b..6b4f40172 100644
--- a/t/app/controller/report_new.t
+++ b/t/app/controller/report_new.t
@@ -607,10 +607,9 @@ foreach my $test (
# receive token
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/confirm that you want to send your\s+report/i, "confirm the problem";
+ like $mech->get_text_body_from_email($email), qr/confirm that you want to send your\s+report/i, "confirm the problem";
- my ($url) = $email->body =~ m{(http://\S+)};
- ok $url, "extracted confirm url '$url'";
+ my $url = $mech->get_link_from_email($email);
# confirm token
$mech->get_ok($url);
@@ -949,10 +948,9 @@ subtest "test report creation for a category that is non public" => sub {
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/confirm that you want to send your\s+report/i, "confirm the problem";
+ like $mech->get_text_body_from_email($email), qr/confirm that you want to send your\s+report/i, "confirm the problem";
- my ($url) = $email->body =~ m{(http://\S+)};
- ok $url, "extracted confirm url '$url'";
+ my $url = $mech->get_link_from_email($email);
# confirm token
$mech->get_ok($url);
@@ -1145,10 +1143,9 @@ for my $test (
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/confirm that you want to send your\s+report/i, "confirm the problem";
+ like $mech->get_text_body_from_email($email), qr/confirm that you want to send your\s+report/i, "confirm the problem";
- my ($url) = $email->body =~ m{(https?://\S+)};
- ok $url, "extracted confirm url '$url'";
+ my $url = $mech->get_link_from_email($email);
# confirm token in order to update the user details
$mech->get_ok($url);
@@ -1315,17 +1312,17 @@ subtest "test Hart" => sub {
# receive token
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/to confirm that you want to send your/i, "confirm the problem";
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/to confirm that you want to send your/i, "confirm the problem";
# does it reference the fact that this report hasn't been sent to Hart?
if ( $test->{national} ) {
- like $email->body, qr/Hart Council is not responsible for this type/i, "mentions report hasn't gone to Hart";
+ like $body, qr/Hart Council is not responsible for this type/i, "mentions report hasn't gone to Hart";
} else {
- unlike $email->body, qr/Hart Council is not responsible for this type/i, "doesn't mention report hasn't gone to Hart";
+ unlike $body, qr/Hart Council is not responsible for this type/i, "doesn't mention report hasn't gone to Hart";
}
- my ($url) = $email->body =~ m{(http://\S+)};
- ok $url, "extracted confirm url '$url'";
+ my $url = $mech->get_link_from_email($email);
# confirm token
FixMyStreet::override_config {
@@ -1541,9 +1538,7 @@ subtest "unresponsive body handling works" => sub {
ok $report, "Found the report";
is $report->bodies_str, undef, "Report not going anywhere";
- my $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/despite not being sent/i, "correct email sent";
+ like $mech->get_text_body_from_email, qr/despite not being sent/i, "correct email sent";
$user->problems->delete;
$mech->clear_emails_ok;
@@ -1577,9 +1572,7 @@ subtest "unresponsive body handling works" => sub {
ok $report, "Found the report";
is $report->bodies_str, undef, "Report not going anywhere";
- $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/despite not being sent/i, "correct email sent";
+ like $mech->get_text_body_from_email, qr/despite not being sent/i, "correct email sent";
$user->problems->delete;
$mech->clear_emails_ok;
@@ -1737,10 +1730,9 @@ subtest "extra google analytics code displayed on email confirmation problem cre
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/confirm that you want to/i, "confirm the problem";
+ like $mech->get_text_body_from_email($email), qr/confirm that you want to/i, "confirm the problem";
- my ($url) = $email->body =~ m{(https?://\S+)};
- ok $url, "extracted confirm url '$url'";
+ my $url = $mech->get_link_from_email($email);
# confirm token in order to update the user details
$mech->get_ok($url);
diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t
index e077a07c9..e1cd0da71 100644
--- a/t/app/controller/report_updates.t
+++ b/t/app/controller/report_updates.t
@@ -362,10 +362,11 @@ for my $test (
$mech->content_contains('Nearly done! Now check your email');
my $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/confirm your update on/i, "Correct email text";
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/confirm your update on/i, "Correct email text";
- my ( $url, $url_token ) = $email->body =~ m{(http://\S+/C/)(\S+)};
+ my $url = $mech->get_link_from_email($email);
+ my ($url_token) = $url =~ m{/C/(\S+)};
ok $url, "extracted confirm url '$url'";
my $token = FixMyStreet::App->model('DB::Token')->find(
@@ -392,7 +393,7 @@ for my $test (
is $update->text, $details->{update}, 'update text';
is $add_alerts, $details->{add_alert} ? 1 : 0, 'do not sign up for alerts';
- $mech->get_ok( $url . $url_token );
+ $mech->get_ok( $url );
$mech->content_contains("/report/$report_id#update_$update_id");
my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => $details->{rznvy} } );
@@ -1000,10 +1001,11 @@ subtest 'submit an update for a registered user, creating update by email' => su
is $user->name, 'Mr Reg', 'name unchanged';
my $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/confirm your update on/i, "Correct email text";
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/confirm your update on/i, "Correct email text";
- my ( $url, $url_token ) = $email->body =~ m{(http://\S+/C/)(\S+)};
+ my $url = $mech->get_link_from_email($email);
+ my ($url_token) = $url =~ m{/C/(\S+)};
ok $url, "extracted confirm url '$url'";
my $token = FixMyStreet::App->model('DB::Token')->find( {
@@ -1021,7 +1023,7 @@ subtest 'submit an update for a registered user, creating update by email' => su
is $update->user->email, 'registered@example.com', 'update email';
is $update->text, 'Update from a user', 'update text';
- $mech->get_ok( $url . $url_token );
+ $mech->get_ok( $url );
$mech->content_contains("/report/$report_id#update_$update_id");
# User should have new name and password
@@ -1514,8 +1516,6 @@ for my $test (
$mech->content_contains( 'Now check your email' );
- $mech->email_count_is(1);
-
my $results = { %{ $test->{fields} }, %{ $test->{changed} }, };
my $update = $report->comments->first;
@@ -1526,10 +1526,11 @@ for my $test (
is $update->anonymous, $test->{anonymous}, 'user anonymous';
my $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/confirm your update on/i, "Correct email text";
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/confirm your update on/i, "Correct email text";
- my ( $url, $url_token ) = $email->body =~ m{(http://\S+/C/)(\S+)};
+ my $url = $mech->get_link_from_email($email);
+ my ($url_token) = $url =~ m{/C/(\S+)};
ok $url, "extracted confirm url '$url'";
my $token = FixMyStreet::App->model('DB::Token')->find(
diff --git a/t/app/helpers/emails/html_test.html b/t/app/helpers/emails/html_test.html
new file mode 100644
index 000000000..49f7b38d3
--- /dev/null
+++ b/t/app/helpers/emails/html_test.html
@@ -0,0 +1,15 @@
+Subject: test email ☺
+
+Hello,
+
+This is a test email where foo: [% foo %].
+
+utf8: 我们应该能够无缝处理UTF8编码
+
+ indented_text
+
+It additionally has an inline image!
+<img src="[% inline_image('t/app/helpers/grey.gif') %]">
+
+Yours,
+FixMyStreet.
diff --git a/t/app/helpers/emails/html_test.txt b/t/app/helpers/emails/html_test.txt
new file mode 100644
index 000000000..692d25ccf
--- /dev/null
+++ b/t/app/helpers/emails/html_test.txt
@@ -0,0 +1,14 @@
+Subject: test email ☺
+
+Hello,
+
+This is a test email where foo: [% foo %].
+
+utf8: 我们应该能够无缝处理UTF8编码
+
+ indented_text
+
+It additionally has an inline image!
+
+Yours,
+FixMyStreet.
diff --git a/templates/email/default/test.txt b/t/app/helpers/emails/test.txt
index 1acd4b6ca..1acd4b6ca 100644
--- a/templates/email/default/test.txt
+++ b/t/app/helpers/emails/test.txt
diff --git a/t/app/helpers/send_email.t b/t/app/helpers/send_email.t
index e2c8688a8..3975002fa 100644
--- a/t/app/helpers/send_email.t
+++ b/t/app/helpers/send_email.t
@@ -2,6 +2,12 @@ use strict;
use warnings;
use utf8;
+package FixMyStreet::Cobrand::Tester;
+use parent 'FixMyStreet::Cobrand::Default';
+sub path_to_email_templates { [ FixMyStreet->path_to( 't', 'app', 'helpers', 'emails') ] }
+
+package main;
+
BEGIN {
use FixMyStreet;
FixMyStreet->test_mode(1);
@@ -28,8 +34,12 @@ $c->stash->{foo} = 'bar';
Email::Send::Test->clear;
# send the test email
-ok $c->send_email( 'test.txt', { to => 'test@recipient.com' } ),
- "sent an email";
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'tester' ],
+}, sub {
+ ok $c->send_email( 'test.txt', { to => 'test@recipient.com' } ),
+ "sent an email";
+};
# check it got templated and sent correctly
my @emails = Email::Send::Test->emails;
@@ -51,9 +61,7 @@ is_string $email->body, $expected_email->body, 'email is as expected';
subtest 'MIME attachments' => sub {
my $data = path(__FILE__)->parent->child('grey.gif')->slurp_raw;
- Email::Send::Test->clear;
- my @emails = Email::Send::Test->emails;
- is scalar(@emails), 0, "reset";
+ $mech->clear_emails_ok;
ok $c->send_email( 'test.txt',
{ to => 'test@recipient.com',
@@ -108,6 +116,20 @@ subtest 'MIME attachments' => sub {
$path->spew($email_as_string);
diag "Saved output in $path";
};
+ $mech->clear_emails_ok;
+};
+
+subtest 'Inline emails!' => sub {
+ ok $c->send_email( 'html_test.txt', { to => 'test@recipient.com' } ), "sent an email with email attachments";
+
+ my $email = $mech->get_email;
+ like $email->debug_structure, qr[
+ \+\ multipart/related.*\n
+ \ {5}\+\ multipart/alternative.*\n
+ \ {10}\+\ text/plain.*\n
+ \ {10}\+\ text/html.*\n
+ \ {5}\+\ image/gif]x;
+ $mech->clear_emails_ok;
};
done_testing;
diff --git a/t/app/model/alert_type.t b/t/app/model/alert_type.t
index e94ee8ce1..4e8817225 100644
--- a/t/app/model/alert_type.t
+++ b/t/app/model/alert_type.t
@@ -145,7 +145,7 @@ for my $test (
my @emails = $mech->get_email;
my $msg = $test->{msg};
for my $email (@emails) {
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email($email);
my $to = $email->header('To');
like $body, qr/$msg/, 'email says problem is ' . $test->{state};
@@ -193,9 +193,8 @@ subtest "correct text for title after URL" => sub {
FixMyStreet::DB->resultset('AlertType')->email_alerts();
};
- my $email = $mech->get_email;
(my $title = $report->title) =~ s/ /\\s+/;
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email;
like $body, qr#report/$report_id\s+-\s+$title#, 'email contains expected title';
};
@@ -330,8 +329,7 @@ foreach my $test (
FixMyStreet::DB->resultset('AlertType')->email_alerts();
};
- my $email = $mech->get_email;
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email;
if ( $test->{nearest} ) {
like $body, $test->{nearest}, 'correct nearest line';
@@ -439,8 +437,7 @@ subtest "check alerts from cobrand send main site url for alerts for different c
FixMyStreet::DB->resultset('AlertType')->email_alerts();
};
- my $email = $mech->get_email;
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email;
my $expected1 = FixMyStreet->config('BASE_URL') . '/report/' . $report_to_county_council->id;
my $expected3 = FixMyStreet->config('BASE_URL') . '/report/' . $report_outside_district->id;
@@ -476,8 +473,7 @@ subtest "check local alerts from cobrand send main site url for alerts for diffe
FixMyStreet::DB->resultset('AlertType')->email_alerts();
- my $email = $mech->get_email;
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email;
my $expected1 = FixMyStreet->config('BASE_URL') . '/report/' . $report_to_county_council->id;
my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('hart')->new();
@@ -505,9 +501,7 @@ subtest "correct i18n-ed summary for state of closed" => sub {
FixMyStreet::DB->resultset('AlertType')->email_alerts();
};
- $mech->email_count_is( 1 );
- my $email = $mech->get_email;
- my $body = $email->body;
+ my $body = $mech->get_text_body_from_email;
my $msg = 'Denne rapporten er for tiden markert som lukket';
like $body, qr/$msg/, 'email says problem is closed, in Norwegian';
};
diff --git a/t/app/model/problem.t b/t/app/model/problem.t
index ea45f7356..836e8a047 100644
--- a/t/app/model/problem.t
+++ b/t/app/model/problem.t
@@ -548,24 +548,25 @@ foreach my $test ( {
like $email->header('To'), $test->{ to }, 'to line looks correct';
is $email->header('From'), sprintf('"%s" <%s>', $test->{ name }, $test->{ email } ), 'from line looks correct';
like $email->header('Subject'), qr/A Title/, 'subject line looks correct';
- like $email->body, qr/A user of FixMyStreet/, 'email body looks a bit like a report';
- like $email->body, qr/Subject: A Title/, 'more email body checking';
- like $email->body, $test->{ dear }, 'Salutation looks correct';
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/A user of FixMyStreet/, 'email body looks a bit like a report';
+ like $body, qr/Subject: A Title/, 'more email body checking';
+ like $body, $test->{ dear }, 'Salutation looks correct';
if ($test->{longitude}) {
- like $email->body, qr{Easting/Northing \(IE\): 297279/362371};
+ like $body, qr{Easting/Northing \(IE\): 297279/362371};
} else {
- like $email->body, qr{Easting/Northing: };
+ like $body, qr{Easting/Northing: };
}
if ( $test->{multiple} ) {
- like $email->body, qr/This email has been sent to several councils /, 'multiple body text correct';
+ like $body, qr/This email has been sent to several councils /, 'multiple body text correct';
} elsif ( $test->{ missing } ) {
- like $email->body, $test->{ missing }, 'missing body information correct';
+ like $body, $test->{ missing }, 'missing body information correct';
}
if ( $test->{url} ) {
my $id = $problem->id;
- like $email->body, qr[$test->{url}fixmystreet.com/report/$id], 'URL present is correct';
+ like $body, qr[$test->{url}fixmystreet.com/report/$id], 'URL present is correct';
}
$problem->discard_changes;
@@ -655,16 +656,18 @@ subtest 'check can turn on report sent email alerts' => sub {
like $email->header('To'),qr/City of Edinburgh Council/, 'to line looks correct';
is $email->header('From'), '"Test User" <system_user@example.com>', 'from line looks correct';
like $email->header('Subject'), qr/A Title/, 'subject line looks correct';
- like $email->body, qr/A user of FixMyStreet/, 'email body looks a bit like a report';
- like $email->body, qr/Subject: A Title/, 'more email body checking';
- like $email->body, qr/Dear City of Edinburgh Council/, 'Salutation looks correct';
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/A user of FixMyStreet/, 'email body looks a bit like a report';
+ like $body, qr/Subject: A Title/, 'more email body checking';
+ like $body, qr/Dear City of Edinburgh Council/, 'Salutation looks correct';
$problem->discard_changes;
ok defined( $problem->whensent ), 'whensent set';
$email = $emails[1];
like $email->header('Subject'), qr/FixMyStreet Report Sent/, 'report sent email title correct';
- like $email->body, qr/to submit your report/, 'report sent body correct';
+ $body = $mech->get_text_body_from_email($email);
+ like $body, qr/to submit your report/, 'report sent body correct';
$send_confirmation_mail_override->restore();
};
diff --git a/t/cobrand/bromley.t b/t/cobrand/bromley.t
index 6066c66b6..e39bcbe4c 100644
--- a/t/cobrand/bromley.t
+++ b/t/cobrand/bromley.t
@@ -103,10 +103,9 @@ for my $test (
};
$mech->content_contains('Nearly done! Now check your email');
- my $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/This update will be sent to Bromley Council/i, "Email indicates problem will be sent to Bromley";
- unlike $email->body, qr/Note that we do not send updates to/i, "Email does not say updates aren't sent to Bromley";
+ my $body = $mech->get_text_body_from_email;
+ like $body, qr/This update will be sent to Bromley Council/i, "Email indicates problem will be sent to Bromley";
+ unlike $body, qr/Note that we do not send updates to/i, "Email does not say updates aren't sent to Bromley";
my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => 'unregistered@example.com' } );
diff --git a/t/cobrand/fixamingata.t b/t/cobrand/fixamingata.t
index 0cf7a31fe..2ef3c09b4 100644
--- a/t/cobrand/fixamingata.t
+++ b/t/cobrand/fixamingata.t
@@ -46,10 +46,11 @@ FixMyStreet::override_config {
FixMyStreet::DB->resultset('Problem')->send_reports();
};
my $email = $mech->get_email;
-like $email->header('Content-Type'), qr/utf-8/, 'encoding looks okay';
+my $plain = $mech->get_text_body_from_email($email, 1);
+like $plain->header('Content-Type'), qr/utf-8/, 'encoding looks okay';
like $email->header('Subject'), qr/Ny rapport: Test Test/, 'subject looks okay';
like $email->header('To'), qr/other\@example.org/, 'to line looks correct';
-like $email->body_str, qr/V\xe4nligen,/, 'signature looks correct';
+like $plain->body_str, qr/V\xe4nligen,/, 'signature looks correct';
$mech->clear_emails_ok;
my $user =
@@ -89,10 +90,10 @@ FixMyStreet::override_config {
FixMyStreet::DB->resultset('AlertType')->email_alerts();
};
-$mech->email_count_is(1);
$email = $mech->get_email;
-like $email->header('Content-Type'), qr/utf-8/, 'encoding looks okay';
-like $email->body_str, qr/V\xe4nligen,/, 'signature looks correct';
+$plain = $mech->get_text_body_from_email($email, 1);
+like $plain->header('Content-Type'), qr/utf-8/, 'encoding looks okay';
+like $plain->body_str, qr/V\xe4nligen,/, 'signature looks correct';
$mech->clear_emails_ok;
subtest "Test ajax decimal points" => sub {
diff --git a/templates/email/bromley/_email_color_overrides.html b/templates/email/bromley/_email_color_overrides.html
new file mode 100644
index 000000000..effe82046
--- /dev/null
+++ b/templates/email/bromley/_email_color_overrides.html
@@ -0,0 +1,19 @@
+[%
+
+color_bromley_green = '#009D57'
+color_bromley_blue = '#5b7893'
+color_bromley_blue_pale = '#ADC3D8'
+
+body_background_color = color_bromley_blue
+body_text_color = color_bromley_blue_pale
+
+header_background_color = color_bromley_green
+header_text_color = color_white
+
+button_background_color = color_bromley_green
+button_text_color = color_white
+
+logo_width = "94" # pixel measurement, but without 'px' suffix
+logo_height = "50" # pixel measurement, but without 'px' suffix
+
+%]
diff --git a/templates/email/bromley/questionnaire.txt b/templates/email/bromley/questionnaire.txt
index 5c0bd2957..fa80ab105 100644
--- a/templates/email/bromley/questionnaire.txt
+++ b/templates/email/bromley/questionnaire.txt
@@ -1,6 +1,6 @@
-Subject: Questionnaire about your report: '[% title %]'
+Subject: Questionnaire about your report: '[% report.title %]'
-Hello [% name %],
+Hello [% report.name %],
[% created %] ago, you reported a problem, the details of
which are at the end of this email. To keep the site
@@ -16,7 +16,7 @@ mailbox, please do not reply.
Your report was as follows:
-[% title %]
+[% report.title %]
-[% detail %]
+[% report.detail %]
diff --git a/templates/email/default/_email_bottom.html b/templates/email/default/_email_bottom.html
new file mode 100644
index 000000000..5f5fdd2b0
--- /dev/null
+++ b/templates/email/default/_email_bottom.html
@@ -0,0 +1,17 @@
+ </tr>
+ <tr>
+ <th colspan="[% email_columns %]" style="[% td_style %][% hint_style %]" class="hint">
+ [% IF email_footer %]
+ [% email_footer %]
+ [% ELSE %]
+ This email was sent automatically, from an unmonitored email account. Please do not reply to it.
+ [% END %]
+ </th>
+ </tr>
+ </table>
+ </th>
+ <th></th>
+ </tr>
+ </table>
+</body>
+</html>
diff --git a/templates/email/default/_email_comment_list.html b/templates/email/default/_email_comment_list.html
new file mode 100644
index 000000000..4fc469b6d
--- /dev/null
+++ b/templates/email/default/_email_comment_list.html
@@ -0,0 +1,14 @@
+[% FOR update IN data %]
+ <div style="[% list_item_style %]">
+ [% IF update.item_photo %]
+ <a href="[% problem_url %]">
+ <img style="[% list_item_photo_style %]" src="[% inline_image(update.get_first_image_fp) %]" alt="">
+ </a>
+ [% END %]
+ <p style="[% list_item_p_style %]">&ldquo;[% update.item_text | html %]&rdquo;</p>
+ <p style="[% list_item_date_style %]">
+ [% update.item_name | html IF update.item_name AND NOT update.item_anonymous -%]
+ [% '(' _ cobrand.prettify_dt(update.confirmed) _ ') ' IF cobrand.include_time_in_update_alerts -%]
+ </p>
+ </div>
+[% END %]
diff --git a/templates/email/default/_email_comment_list.txt b/templates/email/default/_email_comment_list.txt
new file mode 100644
index 000000000..dbf00640f
--- /dev/null
+++ b/templates/email/default/_email_comment_list.txt
@@ -0,0 +1,8 @@
+[% FOR row IN data -%]
+[% row.item_name _ ' : ' IF row.item_name AND NOT row.item_anonymous -%]
+[% '(' _ cobrand.prettify_dt(row.confirmed) _ ') ' IF cobrand.include_time_in_update_alerts -%]
+[% row.item_text %]
+
+------
+
+[% END %]
diff --git a/templates/email/default/_email_report_list.html b/templates/email/default/_email_report_list.html
new file mode 100644
index 000000000..5f7f67864
--- /dev/null
+++ b/templates/email/default/_email_report_list.html
@@ -0,0 +1,19 @@
+[% FOR report IN data %]
+<div style="[% list_item_style %]">
+[% IF report.photo %]
+ <a href="[% cobrand.base_url_for_report( report ) %]/report/[% report.id %]">
+ <img style="[% list_item_photo_style %]" src="[% inline_image(report.get_first_image_fp) %]" alt="">
+ </a>
+[% END %]
+ <h2 style="[% list_item_h2_style %]">
+ <a href="[% cobrand.base_url_for_report( report ) %]/report/[% report.id %]">
+ [%~ report.title | html ~%]
+ </a>
+ </h2>
+ <p style="[% list_item_p_style %]">[% report.detail | html %]</p>
+ <p style="[% list_item_date_style %]">
+ [% cobrand.prettify_dt( report.confirmed ) %].
+ [% report.nearest %]
+ </p>
+</div>
+[% END %]
diff --git a/templates/email/default/_email_report_list.txt b/templates/email/default/_email_report_list.txt
new file mode 100644
index 000000000..3128e2f06
--- /dev/null
+++ b/templates/email/default/_email_report_list.txt
@@ -0,0 +1,8 @@
+[% FOR report IN data -%]
+[% cobrand.base_url_for_report(report) %]/report/[% report.id %] - [% report.title %]
+
+[% report.nearest ~%]
+
+------
+
+[% END %]
diff --git a/templates/email/default/_email_settings.html b/templates/email/default/_email_settings.html
new file mode 100644
index 000000000..73f140743
--- /dev/null
+++ b/templates/email/default/_email_settings.html
@@ -0,0 +1,108 @@
+[%
+
+# The default colours.
+
+color_blue = "#0F87C5"
+color_blue_darker = "#00527C"
+color_blue_pale = "#D6E2EB"
+color_grey = "#D2D2D2"
+color_gunmetal = "#42494C"
+color_gunmetal_light = "#81959D"
+color_yellow = "#FDD008"
+color_red_dark = "#ce2626"
+color_green_dark = "#39a515"
+color_black = "#000000"
+color_white = "#ffffff"
+
+link_text_color = color_blue
+link_hover_text_color = color_blue_darker
+
+body_background_color = color_gunmetal
+body_font_family = "Helvetica, Arial, sans-serif"
+body_text_color = color_gunmetal_light
+
+header_background_color = color_yellow
+header_text_color = color_black
+header_padding = "15px 20px" # a full CSS padding property (eg: top/right/bottom/left)
+
+logo_width = "192" # pixel measurement, but without 'px' suffix
+logo_height = "35" # pixel measurement, but without 'px' suffix
+logo_font_size = "24px"
+
+primary_column_background_color = color_white
+primary_column_text_color = color_black
+secondary_column_background_color = color_blue_pale
+secondary_column_text_color = color_black
+column_divider_color = color_grey
+column_padding = "20" # a single CSS pixel measurement without the "px" suffix
+
+preview_photo_border = "1px solid rgba(0,0,0,0.1)"
+list_item_border_bottom = "1px solid $color_grey"
+
+button_border_radius = "4px" # a full CSS border-radius property
+button_background_color = color_yellow
+button_background_color_fixed = color_green_dark
+button_background_color_notfixed = color_red_dark
+button_text_color = color_black
+button_text_color_fixed = color_white
+button_text_color_notfixed = color_white
+button_font_weight = "bold"
+
+%]
+
+[% # Handy point at which your cobrand can override any of those default colours before the rest of the settings are constructed. %]
+[% TRY %][% PROCESS '_email_color_overrides.html' %][% CATCH file %][% END %]
+
+[%
+
+# Variables used inside the email templates.
+
+table_reset = 'cellspacing="0" cellpadding="0" border="0" width="100%"'
+wrapper_table = 'cellspacing="0" cellpadding="5" border="0" width="100%"'
+
+link_style = "color: $link_text_color;"
+link_hover_style = "text-decoration: none; color: $link_hover_text_color;"
+
+td_style = "font-family: $body_font_family; font-size: 16px; line-height: 21px; font-weight: normal; text-align: left;"
+
+body_style = "margin: 0; background: $body_background_color;"
+wrapper_style = "$td_style background: $body_background_color;"
+
+hint_style = "padding: ${ column_padding }px 0; color: $body_text_color; font-size: 12px; line-height: 18px;"
+header_style = "padding: $header_padding; background: $header_background_color; color: $header_text_color;"
+
+only_column_style = "padding: ${ column_padding }px; vertical-align: top; background-color: $primary_column_background_color; color: $primary_column_text_color;"
+primary_column_style = "vertical-align: top; width: 50%; background-color: $primary_column_background_color; color: $primary_column_text_color;"
+secondary_column_style = "vertical-align: top; width: 50%; background-color: $secondary_column_background_color; color: $secondary_column_text_color; border-left: 1px solid $column_divider_color;"
+
+# Use these to add padding inside primary and secondary columns.
+start_padded_box = '<table cellspacing="0" cellpadding="' _ column_padding _ '" border="0" width="100%"><tr><th style="' _ td_style _ '">'
+end_padded_box = '</th></tr></table>'
+
+logo_style = "font-size: $logo_font_size; line-height: ${ logo_height }px; vertical-align: middle;"
+h1_style = "margin: 0 0 20px 0; font-size: 28px; line-height: 30px;"
+h2_style = "margin: 0 0 20px 0; font-size: 21px; line-height: 24px;"
+p_style = "margin: 0 0 0.8em 0;"
+secondary_p_style = "font-size: 14px; line-height: 20px; $p_style"
+preview_photo_style = "display: block; margin: 0 0 1em 1em; border: $preview_photo_border;"
+map_image_style = "display: block; width: 100%; height: auto;"
+
+list_item_style = "padding-bottom: 20px; margin-bottom: 20px; border-bottom: $list_item_border_bottom;"
+list_item_h2_style = "margin: 0 0 16px 0; font-size: 21px; line-height: 24px;"
+list_item_p_style = "margin: 0 0 16px 0;"
+list_item_date_style = "font-size: 14px; line-height: 20px; margin: 0; color: $color_gunmetal_light;"
+list_item_photo_style = "float: right; margin: 0 0 1em 1em; border: none;"
+
+contact_meta_style = "padding: 15px ${ column_padding }px; vertical-align: top; background-color: $secondary_column_background_color; border-bottom: 1px solid $column_divider_color;"
+contact_th_style = "vertical-align: top; padding: 0.4em 1em 0 0; white-space: nowrap; text-align: left;"
+contact_td_style = "vertical-align: top; padding: 0.4em 0 0.4em 0; width: 100%;"
+
+# The below is so the buttons work okay in Outlook: https://litmus.com/blog/a-guide-to-bulletproof-buttons-in-email-design
+button_style = "display: inline-block; border: 10px solid $button_background_color; border-width: 10px 15px; border-radius: $button_border_radius; background-color: $button_background_color; color: $button_text_color; font-size: 18px; line-height: 21px; font-weight: $button_font_weight; text-decoration: underline;"
+fixed_button_style = "$button_style border-color: $button_background_color_fixed; background-color: $button_background_color_fixed; color: $button_text_color_fixed; margin: 0 0.2em;"
+notfixed_button_style = "$button_style border-color: $button_background_color_notfixed; background-color: $button_background_color_notfixed; color: $button_text_color_notfixed; margin: 0 0.2em;"
+
+%]
+
+[% # Handy point at which your cobrand can override any of the constructed variables before they are sent to the templates. %]
+[% TRY %][% PROCESS '_email_setting_overrides.html' %][% CATCH file %][% END %]
diff --git a/templates/email/default/_email_top.html b/templates/email/default/_email_top.html
new file mode 100644
index 000000000..c599142b7
--- /dev/null
+++ b/templates/email/default/_email_top.html
@@ -0,0 +1,64 @@
+[%
+ # The cobrand might come to us a variety of ways
+ # Alert sets cobrand directly, questionnaire/submit have it in report, otherwise web
+ cobrand = cobrand.moniker OR report.cobrand OR c.cobrand.moniker;
+
+ IF cobrand == 'fixmystreet';
+ SET img_dir = 'fixmystreet.com';
+ ELSE;
+ SET img_dir = cobrand;
+ END -%]
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <style type="text/css">
+ [% # Styles here will be applied by everything except Gmail.com %]
+ a { [% link_style %] }
+ a:hover { [% link_hover_style %] }
+
+ body, table, td, th {
+ font-family: [% body_font_family %] !important;
+ }
+
+ [% # 550px = 5+5+5+520+5+5+5 %]
+ @media only screen and (max-width: 549px) {
+ #main {
+ min-width: 0 !important;
+ }
+ }
+
+ @media only screen and (max-width: 500px) {
+ #main table, #main tr, #main th {
+ display: block !important;
+ }
+
+ #primary_column,
+ #secondary_column {
+ width: auto !important;
+ }
+ }
+ </style>
+</head>
+<body style="[% body_style %]">
+ <table [% wrapper_table %] style="[% wrapper_style %]">
+ <tr>
+ <th></th>
+ <th width="620" style="[% td_style %] min-width: 520px;" id="main">
+ <table [% table_reset %]>
+ <tr>
+ <th colspan="[% email_columns %]" style="[% td_style %][% hint_style %]" class="hint">
+ [% email_summary %]
+ </th>
+ </tr>
+ <tr>
+ <th colspan="[% email_columns %]" style="[% td_style %][% header_style %]">
+ [%~ IF file_exists("web/cobrands/${ img_dir }/images/email-logo.gif") ~%]
+ <img src="[% inline_image('web/cobrands/' _ img_dir _ '/images/email-logo.gif') %]" width="[% logo_width %]" height="[% logo_height %]" alt="[% site_name %]" style="[% logo_style %]"/>
+ [%~ ELSE ~%]
+ <span style="[% logo_style %]">[% site_name %]</span>
+ [% END %]
+ </th>
+ </tr>
+ <tr>
diff --git a/templates/email/default/alert-confirm.html b/templates/email/default/alert-confirm.html
new file mode 100644
index 000000000..9abfea644
--- /dev/null
+++ b/templates/email/default/alert-confirm.html
@@ -0,0 +1,21 @@
+[%
+
+email_summary = "You need to confirm your " _ site_name _ " alert settings before we can send you alerts.";
+email_columns = 1;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% only_column_style %]">
+ <h1 style="[% h1_style %]">Please confirm your email alert&nbsp;settings</h1>
+ <p style="[% p_style %]">Please click on the link below to confirm that you want to receive email alerts within your chosen area.</p>
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% button_style %]" href="[% token_url %]">Yes, send me alerts</a>
+ </p>
+ <p style="[% p_style %]">If you no longer wish to subscribe to alerts in this area, just ignore this email.</p>
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/alert-problem-area.html b/templates/email/default/alert-problem-area.html
new file mode 100644
index 000000000..a18933519
--- /dev/null
+++ b/templates/email/default/alert-problem-area.html
@@ -0,0 +1,19 @@
+[%
+
+email_summary = "New reports in " _ area_name;
+email_columns = 1;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% only_column_style %]">
+ <h1 style="[% h1_style %]">New reports in [% area_name %]</h1>
+ [% INCLUDE '_email_report_list.html' %]
+
+ <p style="[% p_style %]"><a href="[% unsubscribe_url %]">Unsubscribe from alerts about new reports in this area</a></p>
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/alert-problem-area.txt b/templates/email/default/alert-problem-area.txt
index 548befe2f..7bf013cda 100644
--- a/templates/email/default/alert-problem-area.txt
+++ b/templates/email/default/alert-problem-area.txt
@@ -3,7 +3,7 @@ Subject: New [% site_name %] reports in [% area_name %]
The following new [% site_name %] reports have been added in
the [% area_name %] area:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/default/alert-problem-council.html b/templates/email/default/alert-problem-council.html
new file mode 100644
index 000000000..867182e09
--- /dev/null
+++ b/templates/email/default/alert-problem-council.html
@@ -0,0 +1,19 @@
+[%
+
+email_summary = "New reports to ${ area_name }";
+email_columns = 1;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% only_column_style %]">
+ <h1 style="[% h1_style %]">New reports to [% area_name %]</h1>
+ [% INCLUDE '_email_report_list.html' %]
+
+ <p style="[% p_style %]"><a href="[% unsubscribe_url %]">Unsubscribe from alerts about new reports to this area</a></p>
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/alert-problem-council.txt b/templates/email/default/alert-problem-council.txt
index abb704870..ecf671e69 100644
--- a/templates/email/default/alert-problem-council.txt
+++ b/templates/email/default/alert-problem-council.txt
@@ -3,7 +3,7 @@ Subject: New [% site_name %] reports to [% area_name %]
The following new [% site_name %] reports have been sent to
[% area_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/default/alert-problem-nearby.html b/templates/email/default/alert-problem-nearby.html
new file mode 100644
index 000000000..78af4cd84
--- /dev/null
+++ b/templates/email/default/alert-problem-nearby.html
@@ -0,0 +1,19 @@
+[%
+
+email_summary = "New reports within your area";
+email_columns = 1;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% only_column_style %]">
+ <h1 style="[% h1_style %]">New reports within your area</h1>
+ [% INCLUDE '_email_report_list.html' %]
+
+ <p style="[% p_style %]"><a href="[% unsubscribe_url %]">Unsubscribe from alerts about new reports in this area</a></p>
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/alert-problem-nearby.txt b/templates/email/default/alert-problem-nearby.txt
index 1a4f713e8..fdffca5b5 100644
--- a/templates/email/default/alert-problem-nearby.txt
+++ b/templates/email/default/alert-problem-nearby.txt
@@ -3,7 +3,7 @@ Subject: New reports on [% site_name %]
The following [% site_name %] reports have been made within the area
you specified:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/default/alert-problem-ward.html b/templates/email/default/alert-problem-ward.html
new file mode 100644
index 000000000..459bd173c
--- /dev/null
+++ b/templates/email/default/alert-problem-ward.html
@@ -0,0 +1,19 @@
+[%
+
+email_summary = "New reports to " _ area_name _ " within " _ ward_name;
+email_columns = 1;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% only_column_style %]">
+ <h1 style="[% h1_style %]">New reports to [% area_name %] within [% ward_name %]</h1>
+ [% INCLUDE '_email_report_list.html' %]
+
+ <p style="[% p_style %]"><a href="[% unsubscribe_url %]">Unsubscribe from alerts about new reports in this area</a></p>
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/alert-problem-ward.txt b/templates/email/default/alert-problem-ward.txt
index e757a2963..edbed6087 100644
--- a/templates/email/default/alert-problem-ward.txt
+++ b/templates/email/default/alert-problem-ward.txt
@@ -3,7 +3,7 @@ Subject: New [% site_name %] reports to [% area_name %] within [% ward_name %]
The following new [% site_name %] reports have been sent to [% area_name %]
within [% ward_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/default/alert-problem.html b/templates/email/default/alert-problem.html
new file mode 100644
index 000000000..bff65e57a
--- /dev/null
+++ b/templates/email/default/alert-problem.html
@@ -0,0 +1,19 @@
+[%
+
+email_summary = "New reports on " _ site_name;
+email_columns = 1;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% only_column_style %]">
+ <h1 style="[% h1_style %]">New reports on [% site_name %]</h1>
+ [% INCLUDE '_email_report_list.html' %]
+
+ <p style="[% p_style %]"><a href="[% unsubscribe_url %]">Unsubscribe from alerts about new [% site_name %] reports</a></p>
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/alert-problem.txt b/templates/email/default/alert-problem.txt
index 7163ee7bf..87ae1f037 100644
--- a/templates/email/default/alert-problem.txt
+++ b/templates/email/default/alert-problem.txt
@@ -2,7 +2,7 @@ Subject: New reports on [% site_name %]
The following new reports have been added to [% site_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/default/alert-update.html b/templates/email/default/alert-update.html
new file mode 100644
index 000000000..0a8aadab7
--- /dev/null
+++ b/templates/email/default/alert-update.html
@@ -0,0 +1,31 @@
+[%
+
+title = title | html;
+email_summary = "New updates on &ldquo;" _ title _ "&rdquo;";
+email_columns = 2;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% primary_column_style %]" id="primary_column">
+ [% start_padded_box %]
+ <h1 style="[% h1_style %]">New updates on <a href="[% problem_url %]">[% title %]</a></h1>
+ [% INCLUDE '_email_comment_list.html' %]
+ <p style="[% p_style %]"><a href="[% unsubscribe_url %]">Unsubscribe from alerts about this report</a></p>
+ [% end_padded_box %]
+</th>
+<th style="[% td_style %][% secondary_column_style %]" id="secondary_column">
+ <img style="[% map_image_style %]" src="[% inline_image(report.static_map, 'map.jpeg') %]" width="310" height="200" alt="">
+ [% start_padded_box %]
+ [% IF photo %]
+ <img style="[% preview_photo_style %]" src="[% inline_image(report.get_first_image_fp) %]" alt="" align="right">
+ [% END %]
+ <h2 style="[% h2_style %]">[% title | html %]</h2>
+ <p style="[% secondary_p_style %]">[% detail | html %]</p>
+ [% end_padded_box %]
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/alert-update.txt b/templates/email/default/alert-update.txt
index 7722d2c1f..3bf9e4377 100644
--- a/templates/email/default/alert-update.txt
+++ b/templates/email/default/alert-update.txt
@@ -5,11 +5,12 @@ You asked us to send you an email every time an update was made to the
The following updates have been left on this report:
-[% data %]
+[% INCLUDE '_email_comment_list.txt' %]
[% state_message %]
If you would like to view or reply to these updates, please visit the following URL:
+
[% problem_url %]
This email was sent automatically, from an unmonitored email account - so
diff --git a/templates/email/default/change_email.html b/templates/email/default/change_email.html
new file mode 100644
index 000000000..965741eed
--- /dev/null
+++ b/templates/email/default/change_email.html
@@ -0,0 +1,22 @@
+[%
+
+email_summary = "Click this link to change your " _ site_name _ " email address";
+email_columns = 1;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% only_column_style %]">
+ <h1 style="[% h1_style %]">Change your [% site_name %] email&nbsp;address</h1>
+ <p style="[% p_style %]">Please click on the link below to confirm you wish to update your
+email address on [% site_name %].</p>
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% button_style %]" href="[% c.uri_for_action( 'auth/token', token ) %]">Change my email address</a>
+ </p>
+ <p style="[% p_style %]">If you no longer wish to change your email address, just ignore this email.</p>
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/change_email.txt b/templates/email/default/change_email.txt
index 0c5aeac14..8db6b105e 100644
--- a/templates/email/default/change_email.txt
+++ b/templates/email/default/change_email.txt
@@ -1,7 +1,7 @@
-Subject: Updating your [% INCLUDE 'site-name.txt' | trim %] email address
+Subject: Updating your [% site_name %] email address
Please click on the link below to confirm you wish to update your
-email address on [% INCLUDE 'site-name.txt' | trim %].
+email address on [% site_name %].
[% c.uri_for_action( 'auth/token', token ) %]
diff --git a/templates/email/default/contact.html b/templates/email/default/contact.html
new file mode 100644
index 000000000..81f9cb080
--- /dev/null
+++ b/templates/email/default/contact.html
@@ -0,0 +1,45 @@
+[%
+
+subject_html = subject | html;
+name = form_name | html;
+email_summary = "&ldquo;" _ subject_html _ "&rdquo; &ndash; Message from " _ name _ " on " _ host;
+email_columns = 1;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% contact_meta_style %]">
+ <table [% table_reset %]>
+ <tr>
+ <th style="[% contact_th_style %]">From</th>
+ <td style="[% contact_td_style %]">[% name %] &lt;<a href="mailto:[% em | html %]">[% em | html %]</a>&gt;</td>
+ </tr>
+ <tr>
+ <th style="[% contact_th_style %]">IP address</th>
+ <td style="[% contact_td_style %]">[% ip %]</td>
+ </tr>
+ <tr>
+ <th style="[% contact_th_style %]">To</th>
+ <td style="[% contact_td_style %]">[% host %] administrators</td>
+ </tr>
+ </table>
+</th>
+</tr>
+
+<tr>
+<th style="[% td_style %][% only_column_style %]">
+ <h1 style="[% h1_style %]">[% subject | html %]</h1>
+ <p style="[% p_style %]">[% message | html %]</p>
+ [% IF complaint %]
+ <p style="[% secondary_p_style %]">
+ [% complaint | html %]
+ - <a href="[% problem_url %]">Report</a>
+ - <a href="[% admin_url %]">Admin</a>
+ </p>
+ [% END %]
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/contact.txt b/templates/email/default/contact.txt
index 59a778ad5..6e1fd5ac9 100644
--- a/templates/email/default/contact.txt
+++ b/templates/email/default/contact.txt
@@ -2,4 +2,8 @@ Subject: FMS message: [% subject %]
[% message %]
+[% IF complaint %]
+[ [% complaint %] - [% problem_url %] - [% admin_url %] ]
+[% END %]
+
[ Sent by contact.cgi on [% host %]. IP address [% ip %] ]
diff --git a/templates/email/default/login.html b/templates/email/default/login.html
new file mode 100644
index 000000000..b22838d4e
--- /dev/null
+++ b/templates/email/default/login.html
@@ -0,0 +1,22 @@
+[%
+
+email_summary = "Click this link to confirm your email address and log into " _ site_name;
+email_columns = 1;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% only_column_style %]">
+ <h1 style="[% h1_style %]">Thanks for using [% site_name %]</h1>
+ <p style="[% p_style %]">Please click on the link below to confirm your email address and log into [% site_name %].</p>
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% button_style %]" href="[% c.uri_for_action( 'auth/token', token ) %]">Yes, this is my address</a>
+ </p>
+ <p style="[% p_style %]">Once you&rsquo;ve done this, you&rsquo;ll be able to view and manage all reports and
+updates you&rsquo;ve made from the &ldquo;Your account&rdquo; menu on [% site_name %].</p>
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/login.txt b/templates/email/default/login.txt
index 360eb8512..9a57c4fd9 100644
--- a/templates/email/default/login.txt
+++ b/templates/email/default/login.txt
@@ -1,11 +1,11 @@
-Subject: Your [% INCLUDE 'site-name.txt' | trim %] account details
+Subject: Your [% site_name %] account details
Please click on the link below to confirm your email address.
[% c.uri_for_action( 'auth/token', token ) %]
Once you've done this, you'll be able to view and manage all reports and
-updates you've made on [% INCLUDE 'site-name.txt' | trim %].
+updates you've made on [% site_name %].
[% INCLUDE 'signature.txt' %]
diff --git a/templates/email/default/problem-confirm-not-sending.html b/templates/email/default/problem-confirm-not-sending.html
new file mode 100644
index 000000000..6b60afbcf
--- /dev/null
+++ b/templates/email/default/problem-confirm-not-sending.html
@@ -0,0 +1,36 @@
+[%
+
+email_summary = "You need to confirm your " _ site_name _ " report before it can be made public.";
+email_columns = 2;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% primary_column_style %]" id="primary_column">
+ [% start_padded_box %]
+ <h1 style="[% h1_style %]">Please confirm your&nbsp;report</h1>
+ <p style="[% p_style %]">Please click on the link below to confirm that you want your report to appear
+on [% site_name %], despite not being sent to the
+council.</p>
+ <p style="[% p_style %]">Your report will also appear on the [% site_name %] website.</p>
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% button_style %]" href="[% token_url %]">Yes, publish my report</a>
+ </p>
+ <p style="[% p_style %]">If you no longer wish to publish this report, please take no further action.</p>
+ [% end_padded_box %]
+</th>
+<th style="[% td_style %][% secondary_column_style %]" id="secondary_column">
+ <img style="[% map_image_style %]" src="[% inline_image(report.static_map, 'map.jpeg') %]" width="310" height="200" alt="">
+ [% start_padded_box %]
+ [% IF report.photo %]
+ <img style="[% preview_photo_style %]" src="[% inline_image(report.get_first_image_fp) %]" alt="" align="right">
+ [% END %]
+ <h2 style="[% h2_style %]">[% report.title | html %]</h2>
+ <p style="[% secondary_p_style %]">[% report.detail | html %]</p>
+ [% end_padded_box %]
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/problem-confirm-not-sending.txt b/templates/email/default/problem-confirm-not-sending.txt
index 2443805bb..d27b47677 100644
--- a/templates/email/default/problem-confirm-not-sending.txt
+++ b/templates/email/default/problem-confirm-not-sending.txt
@@ -1,10 +1,9 @@
-Subject: Confirm your report on [% INCLUDE 'site-name.txt' | trim %]
+Subject: Confirm your report on [% site_name %]
Hello [% report.name %],
Please click on the link below to confirm that you want your report to appear
-on [% INCLUDE 'site-name.txt' | trim %], despite not being sent to the
-council:
+on [% site_name %], despite not being sent to the council:
[% token_url %]
@@ -22,7 +21,7 @@ And details:
If you no longer wish your report to be displayed on the site, please take no
further action.
-Thank you for supporting [% INCLUDE 'site-name.txt' | trim %].
+Thank you for supporting [% site_name %].
diff --git a/templates/email/default/problem-confirm.html b/templates/email/default/problem-confirm.html
new file mode 100644
index 000000000..cfb199df6
--- /dev/null
+++ b/templates/email/default/problem-confirm.html
@@ -0,0 +1,39 @@
+[%
+
+email_summary = "You need to confirm your " _ site_name _ " report before it can be sent to ${ report.body }.";
+email_columns = 2;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% primary_column_style %]" id="primary_column">
+ [% start_padded_box %]
+ <h1 style="[% h1_style %]">Please confirm your&nbsp;report</h1>
+ <p style="[% p_style %]">Please click on the link below to confirm that you want to send your report to [% report.body %].
+[% IF c.cobrand.is_council && !c.cobrand.owns_problem( report ) %]
+Please note that [% c.cobrand.council_name %] is not responsible for this type
+of problem, so it will instead be sent to [% report.body %].
+[% END %]
+ </p>
+ <p style="[% p_style %]">Your report will also appear on the [% site_name %] website.</p>
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% button_style %]" href="[% token_url %]">Yes, send my report</a>
+ </p>
+ <p style="[% p_style %]">If you no longer wish to send this report, please take no further action.</p>
+ [% end_padded_box %]
+</th>
+<th style="[% td_style %][% secondary_column_style %]" id="secondary_column">
+ <img style="[% map_image_style %]" src="[% inline_image(report.static_map, 'map.jpeg') %]" width="310" height="200" alt="">
+ [% start_padded_box %]
+ [% IF report.photo %]
+ <img style="[% preview_photo_style %]" src="[% inline_image(report.get_first_image_fp) %]" alt="" align="right">
+ [% END %]
+ <h2 style="[% h2_style %]">[% report.title | html %]</h2>
+ <p style="[% secondary_p_style %]">[% report.detail | html %]</p>
+ [% end_padded_box %]
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/problem-confirm.txt b/templates/email/default/problem-confirm.txt
index de671a284..9d0767671 100644
--- a/templates/email/default/problem-confirm.txt
+++ b/templates/email/default/problem-confirm.txt
@@ -1,9 +1,9 @@
-Subject: Confirm your report on [% INCLUDE 'site-name.txt' | trim %]
+Subject: Confirm your report on [% site_name %]
Hello [% report.name %],
Please click on the link below to confirm that you want to send your report to
-[% report.body %]. Note that your report will also appear on the [% INCLUDE 'site-name.txt' | trim %]
+[% report.body %]. Note that your report will also appear on the [% site_name %]
website:
[% token_url %]
@@ -24,7 +24,7 @@ And details:
If you no longer wish to send this report, please take no further action.
-Thank you for submitting a report through [% INCLUDE 'site-name.txt' | trim %].
+Thank you for submitting a report through [% site_name %].
diff --git a/templates/email/default/problem-moderated.html b/templates/email/default/problem-moderated.html
new file mode 100644
index 000000000..b3dd2d353
--- /dev/null
+++ b/templates/email/default/problem-moderated.html
@@ -0,0 +1,38 @@
+[%
+
+email_summary = "Your report on " _ site_name _ " has been moderated.";
+email_columns = 2;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% primary_column_style %]" id="primary_column">
+ [% start_padded_box %]
+ <h1 style="[% h1_style %]">Your report has been&nbsp;moderated</h1>
+[% IF types == 'hide' -%]
+ <p style="[% p_style %]">The report has been hidden from the site.</p>
+[% ELSE %]
+ <p style="[% p_style %]">The following data has been changed: <strong>[% types %]</strong></p>
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% button_style %]" href="[% report_uri %]">View my report</a>
+ </p>
+[% END -%]
+ <p style="[% p_style %]">If you do not think that this report should have been moderated, you may contact
+the team at <a href="[% report_complain_uri %]">[% report_complain_uri %]</a></p>
+ [% end_padded_box %]
+</th>
+<th style="[% td_style %][% secondary_column_style %]" id="secondary_column">
+ <img style="[% map_image_style %]" src="[% inline_image(problem.static_map, 'map.jpeg') %]" width="310" height="200" alt="">
+ [% start_padded_box %]
+ [% IF problem.photo %]
+ <img style="[% preview_photo_style %]" src="[% inline_image(problem.get_first_image_fp) %]" alt="" align="right">
+ [% END %]
+ <h2 style="[% h2_style %]">[% problem.moderation_original_data.title | html %]</h2>
+ <p style="[% secondary_p_style %]">[% problem.moderation_original_data.detail | html %]</p>
+ [% end_padded_box %]
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/problem-moderated.txt b/templates/email/default/problem-moderated.txt
index 70dc5ad11..f69004be2 100644
--- a/templates/email/default/problem-moderated.txt
+++ b/templates/email/default/problem-moderated.txt
@@ -1,8 +1,8 @@
-Subject: Your report on [% INCLUDE 'site-name.txt' | trim %] has been moderated
+Subject: Your report on [% site_name %] has been moderated
Hello [% user.name %],
-Your report on [% INCLUDE 'site-name.txt' | trim %] has been moderated.
+Your report on [% site_name %] has been moderated.
[% IF types == 'hide' -%]
The report has been hidden from the site.
@@ -28,8 +28,7 @@ You can see the report at [% report_uri %]
If you do not think that this report should have been moderated, you may contact
the team at [% report_complain_uri %]
-Thank you for submitting a report through [% INCLUDE 'site-name.txt' | trim %].
-
+Thank you for submitting a report through [% site_name %].
[% INCLUDE 'signature.txt' %]
diff --git a/templates/email/default/questionnaire.html b/templates/email/default/questionnaire.html
new file mode 100644
index 000000000..814e5a658
--- /dev/null
+++ b/templates/email/default/questionnaire.html
@@ -0,0 +1,36 @@
+[%
+
+title = report.title | html;
+email_summary = "Got a minute spare? Let us know what happened to your " _ site_name _ " report about ${ title }.";
+email_columns = 2;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% primary_column_style %]" id="primary_column">
+ [% start_padded_box %]
+ <h1 style="[% h1_style %]">Has your problem been&nbsp;fixed?</h1>
+ <p style="[% p_style %]">[% created %] ago, you reported a problem using [% site_name %].</p>
+ <p style="[% p_style %]">Help us keep [% site_name %] up to date by letting us know whether the problem has been fixed yet:</p>
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% fixed_button_style %]" href="[% url %]">Fixed</a>
+ <a style="[% notfixed_button_style %]" href="[% url %]">Not fixed</a>
+ </p>
+ <p style="[% p_style %]">Thank you! Your feedback is really valuable.</p>
+ [% end_padded_box %]
+</th>
+<th style="[% td_style %][% secondary_column_style %]" id="secondary_column">
+ <img style="[% map_image_style %]" src="[% inline_image(report.static_map, 'map.jpeg') %]" width="310" height="200" alt="">
+ [% start_padded_box %]
+ [% IF report.photo %]
+ <img style="[% preview_photo_style %]" src="[% inline_image(report.get_first_image_fp) %]" alt="" align="right">
+ [% END %]
+ <h2 style="[% h2_style %]">[% title %]</h2>
+ <p style="[% secondary_p_style %]">[% report.detail | html %]</p>
+ [% end_padded_box %]
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/questionnaire.txt b/templates/email/default/questionnaire.txt
index 80b556c41..95acca6ee 100644
--- a/templates/email/default/questionnaire.txt
+++ b/templates/email/default/questionnaire.txt
@@ -1,6 +1,6 @@
-Subject: Questionnaire about your [% site_name %] report: '[% title %]'
+Subject: Questionnaire about your [% site_name %] report: '[% report.title %]'
-Hello [% name %],
+Hello [% report.name %],
[% created %] ago, you reported a problem using [% site_name %].
@@ -16,9 +16,9 @@ updating the status of your problem:
Your report was as follows:
-[% title %]
+[% report.title %]
-[% detail %]
+[% report.detail %]
This email was sent automatically, from an unmonitored email account - so
please do not reply to it.
diff --git a/templates/email/default/submit.html b/templates/email/default/submit.html
new file mode 100644
index 000000000..e5cd8f203
--- /dev/null
+++ b/templates/email/default/submit.html
@@ -0,0 +1,63 @@
+[%
+
+email_summary = "A new problem in your area has been reported by a " _ site_name _ " user.";
+email_footer = "If there is a more appropriate email address for messages about " _ category_footer _ ", please let us know. This will help improve the service for local people. We also welcome any other feedback you may have.";
+email_columns = 2;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% primary_column_style %]" id="primary_column">
+ [% start_padded_box %]
+ <h1 style="[% h1_style %]">New problem in your&nbsp;area</h1>
+ <p style="[% p_style %]">[% missing %][% multiple %]A user of [% site_name %] has submitted the following report
+of a local problem that they believe might require your attention.</p>
+
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% button_style %]" href="[% url %]">Show full report</a>
+ </p>
+ <h2 style="[% h2_style %] margin: 30px 0 10px 0">Reported by:</h2>
+ <table [% table_reset %]>
+ <tr>
+ <th style="[% contact_th_style %]">Name</th>
+ <td style="[% contact_td_style %]">[% name | html %]</td>
+ </tr>
+ <tr>
+ <th style="[% contact_th_style %]">Email</th>
+ <td style="[% contact_td_style %]"><a href="mailto:[% email | html %]">[% email | html %]</a></td>
+ </tr>
+ [% IF phone %]
+ <tr>
+ <th style="[% contact_th_style %]">Phone</th>
+ <td style="[% contact_td_style %]"><a href="tel:[% phone | html %]">[% phone | html %]</a></td>
+ </tr>
+ [% END %]
+ </table>
+ <p style="[% p_style %] margin-top: 0.5em;">Replies to this message will go directly to [% name | html %], the user who reported the problem.</p>
+ [% end_padded_box %]
+</th>
+<th style="[% td_style %][% secondary_column_style %]" id="secondary_column">
+ <img style="[% map_image_style %]" src="[% inline_image(report.static_map, 'map.jpeg') %]" width="310" height="200" alt="">
+ [% start_padded_box %]
+ [% IF has_photo %]
+ <img style="[% preview_photo_style %]" src="[% inline_image(report.get_first_image_fp) %]" alt="" align="right">
+ [% END %]
+ <h2 style="[% h2_style %]">[% title | html %]</h2>
+ [% IF category_line %]
+ <p style="[% secondary_p_style %]">[% category | html %]</p>
+ [% END %]
+ <p style="[% secondary_p_style %]">[% detail | html %]</p>
+ <p style="[% secondary_p_style %]">
+ <strong>Location:</strong>
+ <a href="[% osm_url %]" title="View OpenStreetMap of this location">
+ [%~ latitude %], [% longitude ~%]
+ </a>
+ [% IF closest_address %]<br>[% closest_address | trim | replace("\n\n", "<br>") %][% END %]
+ </p>
+ [% end_padded_box %]
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/default/update-confirm-donotsend.txt b/templates/email/default/update-confirm-donotsend.txt
index bbeffef6e..c9fdef5ea 100644
--- a/templates/email/default/update-confirm-donotsend.txt
+++ b/templates/email/default/update-confirm-donotsend.txt
@@ -1,3 +1,3 @@
Note that we do not send updates to [% update.problem.body %] - they are
-intended as a place for [% INCLUDE 'site-name.txt' | trim %] users to
+intended as a place for [% site_name %] users to
discuss, support, and offer advice.
diff --git a/templates/email/default/update-confirm.html b/templates/email/default/update-confirm.html
new file mode 100644
index 000000000..40841bd82
--- /dev/null
+++ b/templates/email/default/update-confirm.html
@@ -0,0 +1,33 @@
+[%
+
+email_summary = "Confirm your update on " _ site_name;
+email_columns = 2;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% primary_column_style %]" id="primary_column">
+ [% start_padded_box %]
+ <h1 style="[% h1_style %]">Please confirm your&nbsp;update</h1>
+ <p style="[% p_style %]">Please click on the link below to confirm your update on [% site_name %].</p>
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% button_style %]" href="[% token_url %]">Yes, confirm my update</a>
+ </p>
+ <p style="[% p_style %]">[% INCLUDE 'update-confirm-donotsend.txt' %]</p>
+ <p style="[% p_style %]">If you no longer wish to confirm this update, please take no further action.</p>
+ [% end_padded_box %]
+</th>
+<th style="[% td_style %][% secondary_column_style %]" id="secondary_column">
+ <img style="[% map_image_style %]" src="[% inline_image(problem.static_map, 'map.jpeg') %]" width="310" height="200" alt="">
+ [% start_padded_box %]
+ [% IF update.photo %]
+ <img style="[% preview_photo_style %]" src="[% inline_image(update.get_first_image_fp) %]" alt="" align="right">
+ [% END %]
+ <p style="[% secondary_p_style %]">[% update.text | html %]</p>
+ [% end_padded_box %]
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/fiksgatami/alert-problem-area.txt b/templates/email/fiksgatami/alert-problem-area.txt
index 950e9574b..086ea9a4a 100644
--- a/templates/email/fiksgatami/alert-problem-area.txt
+++ b/templates/email/fiksgatami/alert-problem-area.txt
@@ -3,7 +3,7 @@ Subject: Nye saker i [% area_name %] hos FiksGataMi.no
Følgende saker er sendt til
[% area_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Vennlig hilsen,
FiksGataMi-gruppen
diff --git a/templates/email/fiksgatami/alert-problem-council.txt b/templates/email/fiksgatami/alert-problem-council.txt
index 24aa02bc6..e0b0209c8 100644
--- a/templates/email/fiksgatami/alert-problem-council.txt
+++ b/templates/email/fiksgatami/alert-problem-council.txt
@@ -2,7 +2,7 @@ Subject: Nye saker sendt til [% area_name %] via FiksGataMi.no
Følgende saker er sendt til [% area_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Vennlig hilsen,
FiksGataMi-gruppen
diff --git a/templates/email/fiksgatami/alert-problem-nearby.txt b/templates/email/fiksgatami/alert-problem-nearby.txt
index b19b08bea..8ba22709a 100644
--- a/templates/email/fiksgatami/alert-problem-nearby.txt
+++ b/templates/email/fiksgatami/alert-problem-nearby.txt
@@ -2,7 +2,7 @@ Subject: Nye saker i nærheten på FiksGataMi.no
Følgende saker i nærheten er lagt inn på FiksGataMi.no:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Vennlig hilsen,
FiksGataMi-gruppen
diff --git a/templates/email/fiksgatami/alert-problem-ward.txt b/templates/email/fiksgatami/alert-problem-ward.txt
index c7109d5c1..c2e45e7d3 100644
--- a/templates/email/fiksgatami/alert-problem-ward.txt
+++ b/templates/email/fiksgatami/alert-problem-ward.txt
@@ -3,7 +3,7 @@ Subject: Nye saker sendt til [% area_name %] innenfor [% ward_name %] via FiksGa
Følgende saker er sendt til [% area_name %]
innenfor [% ward_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Vennlig hilsen,
FiksGataMi-gruppen
diff --git a/templates/email/fiksgatami/alert-problem.txt b/templates/email/fiksgatami/alert-problem.txt
index ffdcedc2c..f6a962612 100644
--- a/templates/email/fiksgatami/alert-problem.txt
+++ b/templates/email/fiksgatami/alert-problem.txt
@@ -2,7 +2,7 @@ Subject: Nye saker på FiksGataMi.no
Følgende nye saker er lagt til:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Vennlig hilsen,
FiksGataMi-gruppen
diff --git a/templates/email/fiksgatami/alert-update.txt b/templates/email/fiksgatami/alert-update.txt
index 950e33082..c075006aa 100644
--- a/templates/email/fiksgatami/alert-update.txt
+++ b/templates/email/fiksgatami/alert-update.txt
@@ -2,7 +2,7 @@ Subject: Nye oppdateringer for problem - '[% title %]'
Følgende oppdateringer har blitt lagt inn for dette problemet:
-[% data %]
+[% INCLUDE '_email_comment_list.txt' %]
[% state_message %]
diff --git a/templates/email/fiksgatami/contact.txt b/templates/email/fiksgatami/contact.txt
index 59a778ad5..6e1fd5ac9 100644
--- a/templates/email/fiksgatami/contact.txt
+++ b/templates/email/fiksgatami/contact.txt
@@ -2,4 +2,8 @@ Subject: FMS message: [% subject %]
[% message %]
+[% IF complaint %]
+[ [% complaint %] - [% problem_url %] - [% admin_url %] ]
+[% END %]
+
[ Sent by contact.cgi on [% host %]. IP address [% ip %] ]
diff --git a/templates/email/fiksgatami/nn/alert-problem-area.txt b/templates/email/fiksgatami/nn/alert-problem-area.txt
index 24b22b777..37fdc376f 100644
--- a/templates/email/fiksgatami/nn/alert-problem-area.txt
+++ b/templates/email/fiksgatami/nn/alert-problem-area.txt
@@ -3,7 +3,7 @@ Subject: Nye saker i [% area_name %] hos FiksGataMi.no
Følgjande saker er sendt til
[% area_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Venleg helsing,
FiksGataMi-gruppa
diff --git a/templates/email/fiksgatami/nn/alert-problem-council.txt b/templates/email/fiksgatami/nn/alert-problem-council.txt
index 308115de5..36d42d891 100644
--- a/templates/email/fiksgatami/nn/alert-problem-council.txt
+++ b/templates/email/fiksgatami/nn/alert-problem-council.txt
@@ -2,7 +2,7 @@ Subject: Nye saker sendt til [% area_name %] via FiksGataMi.no
Følgjande saker er sendt til [% area_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Venleg helsing,
FiksGataMi-gruppa
diff --git a/templates/email/fiksgatami/nn/alert-problem-nearby.txt b/templates/email/fiksgatami/nn/alert-problem-nearby.txt
index 1d356f938..c67d7a37b 100644
--- a/templates/email/fiksgatami/nn/alert-problem-nearby.txt
+++ b/templates/email/fiksgatami/nn/alert-problem-nearby.txt
@@ -2,7 +2,7 @@ Subject: Nye saker i nærleiken på FiksGataMi.no
Følgjande saker i nærleiken er lagd inn på FiksGataMi.no:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Venleg helsing,
FiksGataMi-gruppa
diff --git a/templates/email/fiksgatami/nn/alert-problem-ward.txt b/templates/email/fiksgatami/nn/alert-problem-ward.txt
index 81896e856..57c95deba 100644
--- a/templates/email/fiksgatami/nn/alert-problem-ward.txt
+++ b/templates/email/fiksgatami/nn/alert-problem-ward.txt
@@ -3,7 +3,7 @@ Subject: Nye saker sendt til [% area_name %] innanfor [% ward_name %] via FiksGa
Følgjande saker er sendt til [% area_name %]
innanfor [% ward_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Venleg helsing,
FiksGataMi-gruppa
diff --git a/templates/email/fiksgatami/nn/alert-problem.txt b/templates/email/fiksgatami/nn/alert-problem.txt
index 0f11f1048..4d788b3ea 100644
--- a/templates/email/fiksgatami/nn/alert-problem.txt
+++ b/templates/email/fiksgatami/nn/alert-problem.txt
@@ -2,7 +2,7 @@ Subject: Nye saker på FiksGataMi.no
Følgjande nye saker er lagt til:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Venleg helsing,
FiksGataMi-gruppa
diff --git a/templates/email/fiksgatami/nn/alert-update.txt b/templates/email/fiksgatami/nn/alert-update.txt
index 1c0422bb7..19b31b7ca 100644
--- a/templates/email/fiksgatami/nn/alert-update.txt
+++ b/templates/email/fiksgatami/nn/alert-update.txt
@@ -2,7 +2,7 @@ Subject: Nye oppdateringar for problem – '[% title %]'
Følgjande oppdateringar har vorte lagt inn for dette problemet:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% state_message %]
diff --git a/templates/email/fiksgatami/questionnaire.txt b/templates/email/fiksgatami/questionnaire.txt
index 202ac4ba5..0ee5f9f08 100644
--- a/templates/email/fiksgatami/questionnaire.txt
+++ b/templates/email/fiksgatami/questionnaire.txt
@@ -1,6 +1,6 @@
Subject: Spørreskjema for din sak på FiksGataMi
-Hei [% name %],
+Hei [% report.name %],
for [% created %] siden, la du til en sak på FiksGataMi.no
med detaljene som vist i denne e-posten. For å holde vår nettside oppdatert
@@ -16,8 +16,8 @@ FiksGataMi-gruppen
Saken du la til var som følger:
-[% title %]
+[% report.title %]
-[% detail %]
+[% report.detail %]
diff --git a/templates/email/fixamingata/alert-problem-area.txt b/templates/email/fixamingata/alert-problem-area.txt
index 29e3bb83f..09ded3c46 100644
--- a/templates/email/fixamingata/alert-problem-area.txt
+++ b/templates/email/fixamingata/alert-problem-area.txt
@@ -2,7 +2,7 @@ Subject: Nya rapporter i [% area_name %] på FixaMinGata
Följande nya rapporter har lagts till inom [% area_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/fixamingata/alert-problem-council.txt b/templates/email/fixamingata/alert-problem-council.txt
index 29e3bb83f..09ded3c46 100644
--- a/templates/email/fixamingata/alert-problem-council.txt
+++ b/templates/email/fixamingata/alert-problem-council.txt
@@ -2,7 +2,7 @@ Subject: Nya rapporter i [% area_name %] på FixaMinGata
Följande nya rapporter har lagts till inom [% area_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/fixamingata/alert-problem-nearby.txt b/templates/email/fixamingata/alert-problem-nearby.txt
index 0462568ac..657ef820a 100644
--- a/templates/email/fixamingata/alert-problem-nearby.txt
+++ b/templates/email/fixamingata/alert-problem-nearby.txt
@@ -2,7 +2,7 @@ Subject: Nya rapporter på FixMyStreet
Följande rapporter har nyligen lagts till på:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/fixamingata/alert-problem-ward.txt b/templates/email/fixamingata/alert-problem-ward.txt
index 29e3bb83f..09ded3c46 100644
--- a/templates/email/fixamingata/alert-problem-ward.txt
+++ b/templates/email/fixamingata/alert-problem-ward.txt
@@ -2,7 +2,7 @@ Subject: Nya rapporter i [% area_name %] på FixaMinGata
Följande nya rapporter har lagts till inom [% area_name %]:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/fixamingata/alert-problem.txt b/templates/email/fixamingata/alert-problem.txt
index 0462568ac..657ef820a 100644
--- a/templates/email/fixamingata/alert-problem.txt
+++ b/templates/email/fixamingata/alert-problem.txt
@@ -2,7 +2,7 @@ Subject: Nya rapporter på FixMyStreet
Följande rapporter har nyligen lagts till på:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
[% signature %]
diff --git a/templates/email/fixamingata/alert-update.txt b/templates/email/fixamingata/alert-update.txt
index 89a9681a8..c5facfca7 100644
--- a/templates/email/fixamingata/alert-update.txt
+++ b/templates/email/fixamingata/alert-update.txt
@@ -8,7 +8,7 @@ uppdateringar, klicka på följande länk:
Följande uppdatering har lämnats för rapporten
[% title %]:
-[% data %]
+[% INCLUDE '_email_comment_list.txt' %]
[% state_message %]
diff --git a/templates/email/fixamingata/contact.txt b/templates/email/fixamingata/contact.txt
index aab7f400f..e08612778 100644
--- a/templates/email/fixamingata/contact.txt
+++ b/templates/email/fixamingata/contact.txt
@@ -1,3 +1,7 @@
Subject: [% subject %] (via FixaMinGata)
[% message %]
+
+[% IF complaint %]
+[ [% complaint %] - [% problem_url %] - [% admin_url %] ]
+[% END %]
diff --git a/templates/email/fixamingata/questionnaire.txt b/templates/email/fixamingata/questionnaire.txt
index cd065d1f1..b59bb8415 100644
--- a/templates/email/fixamingata/questionnaire.txt
+++ b/templates/email/fixamingata/questionnaire.txt
@@ -1,6 +1,6 @@
-Subject: Frågeformulär om '[% title %]'
+Subject: Frågeformulär om '[% report.title %]'
-Hej [% name %],
+Hej [% report.name %],
OBS! Du kan inte svara på detta brev. För att se eller svara på dessa
uppdateringar, klicka på följande länk:
@@ -19,6 +19,6 @@ kommentarsfältet i frågeformuläret.
Ditt rapporterade problem var enligt nedan:
-[% title %]
+[% report.title %]
-[% detail %]
+[% report.detail %]
diff --git a/templates/email/fixmystreet.com/_submit_footer.html b/templates/email/fixmystreet.com/_submit_footer.html
new file mode 100644
index 000000000..b76f128a5
--- /dev/null
+++ b/templates/email/fixmystreet.com/_submit_footer.html
@@ -0,0 +1,9 @@
+This message was sent via FixMyStreet, a project of UKCOD, registered charity
+number 1076346. If there is a more appropriate email address for messages about
+[% category_footer %], please <a href="https://www.fixmystreet.com/contact">let
+us know</a>. This will help improve the service for local people. We also
+welcome any other feedback you may have.
+<br><br>
+FixMyStreet is now available for full integration into council websites, making
+life easier for both you and your residents.
+<a href="https://www.fixmystreet.com/council">Read more</a>
diff --git a/templates/email/fixmystreet.com/submit-oxfordshire.txt b/templates/email/fixmystreet.com/submit-oxfordshire.txt
deleted file mode 100644
index 547f7ce7f..000000000
--- a/templates/email/fixmystreet.com/submit-oxfordshire.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-Subject: FMS Problem Report: [% title %]
-
-Dear [% bodies_name %],
-
-[% missing %][% multiple %]A user of
-FixMyStreet has submitted the following report
-of a local problem that they believe might require your attention.
-
-[% fuzzy %], or to provide an update on the problem,
-please visit the following link:
-
- [% url %]
-
-[% has_photo %]----------
-
-Name: [% name %]
-
-Email: [% email %]
-
-[% phone_line %][% category_line %]Subject: [% title %]
-
-Details: [% detail %]
-
-Easting/Northing: [% easting %]/[% northing %]
-
-Latitude: [% latitude %]
-
-Longitude: [% longitude %]
-
-View OpenStreetMap of this location: [% osm_url %]
-
-[% closest_address %]----------
-
-Replies to this email will go to the user who submitted the problem.
-
-[% signature %]
-
-This message was sent via FixMyStreet, a project of UKCOD, registered charity
-number 1076346. If there is a more appropriate email address for messages about
-[% category_footer %], please let us know by visiting <https://www.fixmystreet.com/contact>.
-This will help improve the service for local people. We
-also welcome any other feedback you may have.
-
-FixMyStreet is now available for full integration into council
-websites, making life easier for both you and your residents.
-Read more here: https://www.fixmystreet.com/council
-
diff --git a/templates/email/fixmystreet.com/submit.html b/templates/email/fixmystreet.com/submit.html
new file mode 100644
index 000000000..e90862ee9
--- /dev/null
+++ b/templates/email/fixmystreet.com/submit.html
@@ -0,0 +1,69 @@
+[%
+
+email_summary = "A new problem in your area has been reported by a " _ site_name _ " user.";
+email_footer = PROCESS '_submit_footer.html';
+email_columns = 2;
+
+PROCESS '_email_settings.html';
+
+INCLUDE '_email_top.html';
+
+%]
+
+<th style="[% td_style %][% primary_column_style %]" id="primary_column">
+ [% start_padded_box %]
+ <h1 style="[% h1_style %]">New problem in your&nbsp;area</h1>
+ <p style="[% p_style %]">[% missing %][% multiple %]A user of [% site_name %] has submitted the following report
+of a local problem that they believe might require your attention.</p>
+
+ <p style="margin: 20px auto; text-align: center">
+ <a style="[% button_style %]" href="[% url %]">Show full report</a>
+ </p>
+ <h2 style="[% h2_style %] margin: 30px 0 10px 0">Reported by:</h2>
+ <table [% table_reset %]>
+ <tr>
+ <th style="[% contact_th_style %]">Name</th>
+ <td style="[% contact_td_style %]">[% name | html %]</td>
+ </tr>
+ <tr>
+ <th style="[% contact_th_style %]">Email</th>
+ <td style="[% contact_td_style %]"><a href="mailto:[% email | html %]">[% email | html %]</a></td>
+ </tr>
+ [% IF phone %]
+ <tr>
+ <th style="[% contact_th_style %]">Phone</th>
+ <td style="[% contact_td_style %]"><a href="tel:[% phone | html %]">[% phone | html %]</a></td>
+ </tr>
+ [% END %]
+ </table>
+ <p style="[% p_style %] margin-top: 0.5em;">Replies to this message will go directly to [% name | html %], the user who reported the problem.</p>
+ [% end_padded_box %]
+</th>
+<th style="[% td_style %][% secondary_column_style %]" id="secondary_column">
+ <img style="[% map_image_style %]" src="[% inline_image(report.static_map, 'map.jpeg') %]" width="310" height="200" alt="">
+ [% start_padded_box %]
+ [% IF has_photo %]
+ <img style="[% preview_photo_style %]" src="[% inline_image(report.get_first_image_fp) %]" alt="" align="right">
+ [% END %]
+ <h2 style="[% h2_style %]">[% title | html %]</h2>
+ [% IF category_line %]
+ <p style="[% secondary_p_style %]">[% category | html %]</p>
+ [% END %]
+ <p style="[% secondary_p_style %]">[% detail | html %]</p>
+ [% IF additional_information %]
+ <p style="[% secondary_p_style %]">[% additional_information %]</p>
+ [% END %]
+ <p style="[% secondary_p_style %]">
+ <strong>Location:</strong>
+ <br>Easting/Northing
+ [%~ " (IE)" IF coordsyst == "I" ~%]
+ : [% easting %]/[% northing %]
+ (<a href="[% osm_url %]" title="View OpenStreetMap of this location">
+ [%~ latitude %], [% longitude ~%]
+ </a>)
+ [% IF closest_address %]<br>[% closest_address | trim | replace("\n\n", "<br>") %][% END %]
+ </p>
+ [% end_padded_box %]
+</th>
+
+[% INCLUDE '_email_bottom.html' %]
diff --git a/templates/email/fixmystreet.com/submit.txt b/templates/email/fixmystreet.com/submit.txt
index 735fdf37d..c30244db9 100644
--- a/templates/email/fixmystreet.com/submit.txt
+++ b/templates/email/fixmystreet.com/submit.txt
@@ -3,7 +3,7 @@ Subject: Problem Report: [% title %]
Dear [% bodies_name %],
[% missing %][% multiple %]A user of
-FixMyStreet has submitted the following report
+[% site_name %] has submitted the following report
of a local problem that they believe might require your attention.
[% fuzzy %], or to provide an update on the problem,
@@ -21,6 +21,8 @@ Email: [% email %]
Details: [% detail %]
+[% additional_information %]
+
Easting/Northing
[%- " (IE)" IF coordsyst == "I" -%]
: [% easting %]/[% northing %]
diff --git a/templates/email/fixmystreet.com/update-confirm-donotsend.txt b/templates/email/fixmystreet.com/update-confirm-donotsend.txt
index 2e04dc0bf..43be8fe26 100644
--- a/templates/email/fixmystreet.com/update-confirm-donotsend.txt
+++ b/templates/email/fixmystreet.com/update-confirm-donotsend.txt
@@ -1,8 +1,8 @@
[% IF update.problem.bodies_str != 2482 AND update.problem.bodies_str != 2347 %]
Note that we do not send updates to [% update.problem.body %] - they are
-intended as a place for [% INCLUDE 'site-name.txt' | trim %] users to
+intended as a place for [% site_name %] users to
discuss, support, and offer advice.
[% ELSE %]
This update will be sent to [% update.problem.body %] and will
-also be displayed on the [% INCLUDE 'site-name.txt' | trim %] website.
+also be displayed on the [% site_name %] website.
[% END %]
diff --git a/templates/email/greenwich/_email_color_overrides.html b/templates/email/greenwich/_email_color_overrides.html
new file mode 100644
index 000000000..a132a3873
--- /dev/null
+++ b/templates/email/greenwich/_email_color_overrides.html
@@ -0,0 +1,20 @@
+[%
+
+color_greenwich_red = '#D42828'
+color_greenwich_gunmetal = '#4b5459'
+color_greenwich_pale_gunmetal = '#e0e6e9'
+
+body_background_color = color_greenwich_gunmetal
+body_text_color = color_greenwich_pale_gunmetal
+
+header_background_color = color_greenwich_pale_gunmetal
+header_text_color = color_greenwich_red
+
+secondary_column_background_color = color_greenwich_pale_gunmetal
+
+button_background_color = color_greenwich_pale_gunmetal
+
+logo_width = "96" # pixel measurement, but without 'px' suffix
+logo_height = "50" # pixel measurement, but without 'px' suffix
+
+%]
diff --git a/templates/email/greenwich/_email_setting_overrides.html b/templates/email/greenwich/_email_setting_overrides.html
new file mode 100644
index 000000000..910e5d455
--- /dev/null
+++ b/templates/email/greenwich/_email_setting_overrides.html
@@ -0,0 +1,5 @@
+[%
+
+header_style = "$header_style border-bottom: 4px solid $color_greenwich_red;"
+
+%] \ No newline at end of file
diff --git a/templates/email/harrogate/submit.txt b/templates/email/harrogate/submit.txt
deleted file mode 100644
index a4dcd5220..000000000
--- a/templates/email/harrogate/submit.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-Subject: Problem Report: [% title %]
-
-Dear [% bodies_name %],
-
-[% missing %][% multiple %]A user of
-FixMyStreet has submitted the following report
-of a local problem that they believe might require your attention.
-
-[% fuzzy %], or to provide an update on the problem,
-please visit the following link:
-
- [% url %]
-
-[% has_photo %]----------
-
-Name: [% name %]
-
-Email: [% email %]
-
-[% phone_line %][% category_line %]Subject: [% title %]
-
-[% detail %] [% additional_information %]
-
-Easting/Northing: [% easting %]/[% northing %]
-
-Latitude: [% latitude %]
-
-Longitude: [% longitude %]
-
-View OpenStreetMap of this location: [% osm_url %]
-
-[% closest_address %]----------
-
-Replies to this email will go to the user who submitted the problem.
-
-[% signature %]
-
-This message was sent via FixMyStreet, a project of UKCOD, registered charity
-number 1076346. If there is a more appropriate email address for messages about
-[% category_footer %], please let us know by visiting <https://www.fixmystreet.com/contact>.
-This will help improve the service for local people. We
-also welcome any other feedback you may have.
-
-FixMyStreet is now available for full integration into council
-websites, making life easier for both you and your residents.
-Read more here: https://www.fixmystreet.com/council
-
diff --git a/templates/email/oxfordshire/_email_color_overrides.html b/templates/email/oxfordshire/_email_color_overrides.html
new file mode 100644
index 000000000..cb2662d81
--- /dev/null
+++ b/templates/email/oxfordshire/_email_color_overrides.html
@@ -0,0 +1,17 @@
+[%
+
+color_oxfordshire_green = '#339E00'
+color_oxfordshire_pale_green = '#f6fcf0'
+
+header_background_color = color_oxfordshire_green
+header_text_color = color_white
+
+secondary_column_background_color = color_oxfordshire_pale_green
+
+button_background_color = color_oxfordshire_green
+button_text_color = color_white
+
+logo_width = "160" # pixel measurement, but without 'px' suffix
+logo_height = "35" # pixel measurement, but without 'px' suffix
+
+%]
diff --git a/templates/email/oxfordshire/submit.txt b/templates/email/oxfordshire/submit.txt
deleted file mode 100644
index 547f7ce7f..000000000
--- a/templates/email/oxfordshire/submit.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-Subject: FMS Problem Report: [% title %]
-
-Dear [% bodies_name %],
-
-[% missing %][% multiple %]A user of
-FixMyStreet has submitted the following report
-of a local problem that they believe might require your attention.
-
-[% fuzzy %], or to provide an update on the problem,
-please visit the following link:
-
- [% url %]
-
-[% has_photo %]----------
-
-Name: [% name %]
-
-Email: [% email %]
-
-[% phone_line %][% category_line %]Subject: [% title %]
-
-Details: [% detail %]
-
-Easting/Northing: [% easting %]/[% northing %]
-
-Latitude: [% latitude %]
-
-Longitude: [% longitude %]
-
-View OpenStreetMap of this location: [% osm_url %]
-
-[% closest_address %]----------
-
-Replies to this email will go to the user who submitted the problem.
-
-[% signature %]
-
-This message was sent via FixMyStreet, a project of UKCOD, registered charity
-number 1076346. If there is a more appropriate email address for messages about
-[% category_footer %], please let us know by visiting <https://www.fixmystreet.com/contact>.
-This will help improve the service for local people. We
-also welcome any other feedback you may have.
-
-FixMyStreet is now available for full integration into council
-websites, making life easier for both you and your residents.
-Read more here: https://www.fixmystreet.com/council
-
diff --git a/templates/email/warwickshire/_email_color_overrides.html b/templates/email/warwickshire/_email_color_overrides.html
new file mode 100644
index 000000000..6528f0a5c
--- /dev/null
+++ b/templates/email/warwickshire/_email_color_overrides.html
@@ -0,0 +1,17 @@
+[%
+
+color_warwickshire_green = '#006d3c'
+color_warwickshire_pale_green = '#F9FFF8'
+
+header_background_color = color_warwickshire_green
+header_text_color = color_white
+
+secondary_column_background_color = color_warwickshire_pale_green
+
+button_background_color = color_warwickshire_green
+button_text_color = color_white
+
+logo_width = "112" # pixel measurement, but without 'px' suffix
+logo_height = "50" # pixel measurement, but without 'px' suffix
+
+%]
diff --git a/templates/email/zurich/alert-moderation-overdue.txt b/templates/email/zurich/alert-moderation-overdue.txt
index 869f379e5..914f4607c 100644
--- a/templates/email/zurich/alert-moderation-overdue.txt
+++ b/templates/email/zurich/alert-moderation-overdue.txt
@@ -2,7 +2,7 @@ Subject: eskalierte Meldungen auf Züri wie neu
Die folgenden Meldungen auf <<Züri wie neu>> sind älter als einen Tag und müssen dringend bearbeitet werden:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Um diese Meldungen zu moderieren, klicken Sie auf folgende URL:
diff --git a/templates/email/zurich/alert-overdue.txt b/templates/email/zurich/alert-overdue.txt
index 7e7914b46..fa5457cd7 100644
--- a/templates/email/zurich/alert-overdue.txt
+++ b/templates/email/zurich/alert-overdue.txt
@@ -2,7 +2,7 @@ Subject: Rückmeldung erforderlich auf Züri wie neu
Die folgenden Meldungen wurden eskaliert, da sie nicht innerhalb von fünf Tagen beantwortet worden sind:
-[% data %]
+[% INCLUDE '_email_report_list.txt' %]
Um diese Meldungen zu bearbeiten, klicken Sie auf folgende URL:
diff --git a/templates/email/zurich/alert-update.txt b/templates/email/zurich/alert-update.txt
index 144047599..30b822f9d 100644
--- a/templates/email/zurich/alert-update.txt
+++ b/templates/email/zurich/alert-update.txt
@@ -2,7 +2,7 @@ Subject: New update on report - '[% title %]'
The following update has been left on this report:
-[% data %]
+[% INCLUDE '_email_comment_list.txt' %]
To view this report on the site, please visit the following URL:
[% problem_url %]
diff --git a/web/cobrands/bromley/images/email-logo.gif b/web/cobrands/bromley/images/email-logo.gif
new file mode 100644
index 000000000..ffe6f0bbc
--- /dev/null
+++ b/web/cobrands/bromley/images/email-logo.gif
Binary files differ
diff --git a/web/cobrands/fixmystreet.com/images/email-logo.gif b/web/cobrands/fixmystreet.com/images/email-logo.gif
new file mode 100644
index 000000000..8b954a81a
--- /dev/null
+++ b/web/cobrands/fixmystreet.com/images/email-logo.gif
Binary files differ
diff --git a/web/cobrands/greenwich/images/email-logo.gif b/web/cobrands/greenwich/images/email-logo.gif
new file mode 100644
index 000000000..8931899f8
--- /dev/null
+++ b/web/cobrands/greenwich/images/email-logo.gif
Binary files differ
diff --git a/web/cobrands/oxfordshire/images/email-logo.gif b/web/cobrands/oxfordshire/images/email-logo.gif
new file mode 100644
index 000000000..2590e083e
--- /dev/null
+++ b/web/cobrands/oxfordshire/images/email-logo.gif
Binary files differ
diff --git a/web/cobrands/warwickshire/images/email-logo.gif b/web/cobrands/warwickshire/images/email-logo.gif
new file mode 100644
index 000000000..76d71328b
--- /dev/null
+++ b/web/cobrands/warwickshire/images/email-logo.gif
Binary files differ