diff options
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 %]">“[% update.item_text | html %]”</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 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 “" _ 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 %]">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 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 = "“" _ subject_html _ "” – 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 %] <<a href="mailto:[% em | html %]">[% em | html %]</a>></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’ve done this, you’ll be able to view and manage all reports and +updates you’ve made from the “Your account” 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 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 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 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 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 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 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 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 Binary files differnew file mode 100644 index 000000000..ffe6f0bbc --- /dev/null +++ b/web/cobrands/bromley/images/email-logo.gif diff --git a/web/cobrands/fixmystreet.com/images/email-logo.gif b/web/cobrands/fixmystreet.com/images/email-logo.gif Binary files differnew file mode 100644 index 000000000..8b954a81a --- /dev/null +++ b/web/cobrands/fixmystreet.com/images/email-logo.gif diff --git a/web/cobrands/greenwich/images/email-logo.gif b/web/cobrands/greenwich/images/email-logo.gif Binary files differnew file mode 100644 index 000000000..8931899f8 --- /dev/null +++ b/web/cobrands/greenwich/images/email-logo.gif diff --git a/web/cobrands/oxfordshire/images/email-logo.gif b/web/cobrands/oxfordshire/images/email-logo.gif Binary files differnew file mode 100644 index 000000000..2590e083e --- /dev/null +++ b/web/cobrands/oxfordshire/images/email-logo.gif diff --git a/web/cobrands/warwickshire/images/email-logo.gif b/web/cobrands/warwickshire/images/email-logo.gif Binary files differnew file mode 100644 index 000000000..76d71328b --- /dev/null +++ b/web/cobrands/warwickshire/images/email-logo.gif |