[MAILPOET-1571]
This commit is contained in:
Pavel Dohnal
2019-01-10 11:04:51 +01:00
parent 96f2f79d48
commit ef5eba31d1
7 changed files with 709 additions and 23 deletions

View File

@ -21,9 +21,9 @@ class Daemon {
CronHelper::saveDaemon($settings_daemon_data);
try {
$this->executeMigrationWorker();
$this->executeStatsNotificationsWorker();
$this->executeScheduleWorker();
$this->executeQueueWorker();
$this->executeStatsNotificationsWorker();
$this->executeSendingServiceKeyCheckWorker();
$this->executePremiumKeyCheckWorker();
$this->executeBounceWorker();

View File

@ -2,17 +2,16 @@
namespace MailPoet\Cron\Workers\StatsNotifications;
use Carbon\Carbon;
use MailPoet\Config\Renderer;
use MailPoet\Cron\CronHelper;
use MailPoet\Mailer\Mailer;
use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterLink;
use MailPoet\Models\ScheduledTask;
use MailPoet\Models\Setting;
use MailPoet\Tasks\Sending;
/**
* TODO:
* - add processing of this task to Daemon
* - check JIRA what to do next and how to send the newsletter
* - see \MailPoet\Subscribers\NewSubscriberNotificationMailer how to send an email, now with DI everything should be easy
*/
class Worker {
const TASK_TYPE = 'stats_notification';
@ -38,16 +37,19 @@ class Worker {
/** @throws \Exception */
function process() {
$settings = Setting::getValue(self::SETTINGS_KEY);
try {
$this->mailer->getSenderNameAndAddress($this->constructSenderEmail());
$this->mailer->send($this->constructNewsletter(), $settings['address']);
} catch(\Exception $e) {
if(WP_DEBUG) {
throw $e;
$this->mailer->sender = $this->mailer->getSenderNameAndAddress($this->constructSenderEmail());
foreach($this->getTasks() as $task) {
try {
$this->mailer->send($this->constructNewsletter($task), $settings['address']);
} catch(\Exception $e) {
//if(WP_DEBUG) {
throw $e;
//}
} finally {
$this->markTaskAsFinished($task);
}
CronHelper::enforceExecutionLimit($this->timer);
}
CronHelper::enforceExecutionLimit($this->timer);
}
private function constructSenderEmail() {
@ -62,18 +64,62 @@ class Worker {
];
}
private function constructNewsletter() {
$context = [
'link_settings' => get_site_url(null, '/wp-admin/admin.php?page=mailpoet-settings'),
'link_premium' => get_site_url(null, '/wp-admin/admin.php?page=mailpoet-premium'),
];
private function getTasks() {
$date = new Carbon();
return ScheduledTask::orderByAsc('priority')
->orderByAsc('updated_at')
->whereNull('deleted_at')
->where('status', ScheduledTask::STATUS_SCHEDULED)
->whereLte('scheduled_at', $date)
->where('type', self::TASK_TYPE)
->limit(Sending::RESULT_BATCH_SIZE)
->findMany();
}
private function constructNewsletter(ScheduledTask $task) {
$newsletter = $this->getNewsletter($task);
$link = NewsletterLink::findTopLinkForNewsletter($newsletter);
$context = $this->prepareContext($newsletter, $link);
return [
'subject' => sprintf(__('New subscriber to ', 'mailpoet')),
'subject' => sprintf(_x('Stats for email %s', 'title of an automatic email containing statistics (newsletter open rate, click rate, etc)', 'mailpoet'), $newsletter->subject),
'body' => [
'html' => $this->renderer->render('emails/newSubscriberNotification.html', $context),
'text' => $this->renderer->render('emails/newSubscriberNotification.txt', $context),
'html' => $this->renderer->render('emails/statsNotification.html', $context),
],
];
}
private function getNewsletter(ScheduledTask $task) {
$statsNotificationModel = $task->statsNotification()->findOne();
return $statsNotificationModel
->newsletter()
->findOne()
->withSendingQueue()
->withTotalSent()
->withStatistics();
}
private function prepareContext(Newsletter $newsletter, NewsletterLink $link) {
return [
'subject' => $newsletter->subject,
'preheader' => sprintf(_x(
'%1$s%% opens, %2$s%% clicks, %3$s%% unsubscribes in a nutshell.', 'newsletter open rate, click rate and unsubscribe rate', 'mailpoet'),
number_format(($newsletter->statistics['clicked'] * 100) / $newsletter->total_sent, 2),
number_format(($newsletter->statistics['opened'] * 100) / $newsletter->total_sent,2),
number_format(($newsletter->statistics['unsubscribed'] * 100) / $newsletter->total_sent,2)
),
'topLinkClicks' => $link->clicksCount,
'topLink' => $link->url,
'linkSettings' => get_site_url(null, '/wp-admin/admin.php?page=mailpoet-settings#basics'),
'linkStats' => get_site_url(null, '/wp-admin/admin.php?page=mailpoet-newsletters#/stats/' . $newsletter->id()),
'premiumPluginActive' => is_plugin_active('mailpoet-premium/mailpoet-premium.php'),
];
}
private function markTaskAsFinished(ScheduledTask $task) {
$task->status = ScheduledTask::STATUS_COMPLETED;
$task->processed_at = new Carbon;
$task->scheduled_at = null;
$task->save();
}
}

View File

@ -5,4 +5,19 @@ if(!defined('ABSPATH')) exit;
class NewsletterLink extends Model {
public static $_table = MP_NEWSLETTER_LINKS_TABLE;
static function findTopLinkForNewsletter(Newsletter $newsletter) {
return self::selectExpr('links.*')
->selectExpr('count(*)', 'clicksCount')
->tableAlias('links')
->innerJoin(StatisticsClicks::$_table,
array('clicks.link_id', '=', 'links.id'),
'clicks')
->where('newsletter_id', $newsletter->id())
->groupBy('links.id')
->orderByDesc('clicksCount')
->limit(1)
->findOne();
}
}

View File

@ -32,6 +32,15 @@ class ScheduledTask extends Model {
);
}
/** @return StatsNotification */
function statsNotification() {
return $this->hasOne(
StatsNotification::class,
'task_id',
'id'
);
}
function pause() {
$this->set('status', self::STATUS_PAUSED);
$this->save();

View File

@ -5,6 +5,15 @@ namespace MailPoet\Models;
class StatsNotification extends Model {
public static $_table = MP_STATS_NOTIFICATIONS_TABLE;
/** @return Newsletter */
public function newsletter() {
return $this->hasOne(
Newsletter::class,
'id',
'newsletter_id'
);
}
/** @return StatsNotification */
static function createOrUpdate($data = array()) {
$model = null;

View File

@ -0,0 +1,186 @@
<?php
namespace MailPoet\Cron\Workers\StatsNotifications;
use MailPoet\Config\Renderer;
use MailPoet\Mailer\Mailer;
use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterLink;
use MailPoet\Models\ScheduledTask;
use MailPoet\Models\SendingQueue;
use MailPoet\Models\Setting;
use MailPoet\Models\StatisticsClicks;
use MailPoet\Models\StatisticsOpens;
use MailPoet\Models\StatisticsUnsubscribes;
use MailPoet\Models\StatsNotification;
use PHPUnit\Framework\MockObject\MockObject;
class WorkerTest extends \MailPoetTest {
/** @var Scheduler */
private $stats_notifications;
/** @var MockObject */
private $mailer;
/** @var MockObject */
private $renderer;
function _before() {
$this->mailer = $this->createMock(Mailer::class);
$this->renderer = $this->createMock(Renderer::class);
$this->stats_notifications = new Worker($this->mailer, $this->renderer);
Setting::setValue(Worker::SETTINGS_KEY, [
'enabled' => true,
'address' => 'email@example.com'
]);
$newsletter = Newsletter::createOrUpdate([
'subject' => 'Email Subject1',
'type' => Newsletter::TYPE_STANDARD,
]);
$sending_task = ScheduledTask::createOrUpdate([
'type' => 'sending',
'status' => ScheduledTask::STATUS_COMPLETED,
]);
$stats_notifications_task = ScheduledTask::createOrUpdate([
'type' => Worker::TASK_TYPE,
'status' => ScheduledTask::STATUS_SCHEDULED,
'scheduled_at' => '2017-01-02 12:13:14',
'processed_at' => null,
]);
StatsNotification::createOrUpdate([
'newsletter_id' => $newsletter->id(),
'task_id' => $stats_notifications_task->id(),
]);
$queue = SendingQueue::createOrUpdate([
'newsletter_rendered_subject' => 'Email Subject',
'task_id' => $sending_task->id(),
'newsletter_id' => $newsletter->id(),
'count_processed' => 5,
]);
$link = NewsletterLink::createOrUpdate([
'url' => 'Link url',
'newsletter_id' => $newsletter->id(),
'queue_id' => $queue->id(),
'hash' => 'xyz',
]);
StatisticsClicks::createOrUpdate([
'newsletter_id' => $newsletter->id(),
'queue_id' => $queue->id(),
'subscriber_id' => '5',
'link_id' => $link->id(),
'count' => 5,
'created_at' => '2018-01-02 15:16:17',
]);
$link2 = NewsletterLink::createOrUpdate([
'url' => 'Link url2',
'newsletter_id' => $newsletter->id(),
'queue_id' => $queue->id(),
'hash' => 'xyzd',
]);
StatisticsClicks::createOrUpdate([
'newsletter_id' => $newsletter->id(),
'queue_id' => $queue->id(),
'subscriber_id' => '6',
'link_id' => $link2->id(),
'count' => 5,
'created_at' => '2018-01-02 15:16:17',
]);
StatisticsClicks::createOrUpdate([
'newsletter_id' => $newsletter->id(),
'queue_id' => $queue->id(),
'subscriber_id' => '7',
'link_id' => $link2->id(),
'count' => 5,
'created_at' => '2018-01-02 15:16:17',
]);
StatisticsOpens::createOrUpdate([
'subscriber_id' => '10',
'newsletter_id' => $newsletter->id(),
'queue_id' => $queue->id(),
'created_at' => '2017-01-02 12:23:45',
]);
StatisticsOpens::createOrUpdate([
'subscriber_id' => '11',
'newsletter_id' => $newsletter->id(),
'queue_id' => $queue->id(),
'created_at' => '2017-01-02 21:23:45',
]);
StatisticsUnsubscribes::createOrUpdate([
'subscriber_id' => '12',
'newsletter_id' => $newsletter->id(),
'queue_id' => $queue->id(),
'created_at' => '2017-01-02 21:23:45',
]);
}
function testRendersTemplate() {
$this->renderer->expects($this->once())
->method('render')
->with(
$this->stringContains('statsNotification.html'),
$this->callback(function($context){
return is_array($context);
}));
$this->stats_notifications->process();
}
function testAddsSubjectToContext() {
$this->renderer->expects($this->once())
->method('render')
->with(
$this->stringContains('statsNotification.html'),
$this->callback(function($context){
return $context['subject'] === 'Email Subject1';
}));
$this->stats_notifications->process();
}
function testAddsPreHeaderToContext() {
$this->renderer->expects($this->once())
->method('render')
->with(
$this->stringContains('statsNotification.html'),
$this->callback(function($context){
return $context['preheader'] === '60.00% opens, 40.00% clicks, 20.00% unsubscribes in a nutshell.';
}));
$this->stats_notifications->process();
}
function testAddsWPUrlsToContext() {
$this->renderer->expects($this->once())
->method('render')
->with(
$this->stringContains('statsNotification.html'),
$this->callback(function($context){
return strpos($context['linkSettings'], 'mailpoet-settings')
&& strpos($context['linkStats'], 'mailpoet-newsletters#/stats');
}));
$this->stats_notifications->process();
}
function testAddsLinksToContext() {
$this->renderer->expects($this->once())
->method('render')
->with(
$this->stringContains('statsNotification.html'),
$this->callback(function($context){
return ($context['topLink'] === 'Link url2')
&& ($context['topLinkClicks'] === '2');
}));
$this->stats_notifications->process();
}
function testSends() {
$this->mailer->expects($this->once())
->method('send');
$this->stats_notifications->process();
}
}

View File

@ -0,0 +1,421 @@
<html lang="en" style="margin:0;padding:0">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="format-detection" content="telephone=no" />
<title><%= subject %></title>
<style type="text/css"> @media screen and (max-width: 480px) {
.mailpoet_button {width:100% !important;}
}
@media screen and (max-width: 599px) {
.mailpoet_header {
padding: 10px 20px;
}
.mailpoet_button {
width: 100% !important;
padding: 5px 0 !important;
box-sizing:border-box !important;
}
div, .mailpoet_cols-two {
max-width: 100% !important;
}
}
</style>
</head>
<body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" style="margin:0;padding:0;background-color:#f0f0f0">
<table class="mailpoet_template" border="0" width="100%" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tbody>
<tr>
<td class="mailpoet_preheader" style="-webkit-text-size-adjust:none;font-size:1px;line-height:1px;color:#ffffff;border-collapse:collapse;display:none;visibility:hidden;mso-hide:all;max-height:0;max-width:0;opacity:0;overflow:hidden" height="1">
<%= preheader %>
</td>
</tr>
<tr>
<td align="center" class="mailpoet-wrapper" valign="top" style="border-collapse:collapse;background-color:#f0f0f0"><!--[if mso]>
<table align="center" border="0" cellspacing="0" cellpadding="0"
width="660">
<tr>
<td class="mailpoet_content-wrapper" align="center" valign="top" width="660">
<![endif]--><table class="mailpoet_content-wrapper" border="0" width="660" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;max-width:660px;width:100%;border-collapse:collapse;background-color:#ffffff">
<tbody>
<tr>
<td class="mailpoet_content" align="center" style="border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tbody>
<tr>
<td style="padding-left:0;padding-right:0;border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" class="mailpoet_cols-one" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;border-collapse:collapse">
<tbody>
<tr>
<td class="mailpoet_spacer" height="36" valign="top" style="border-collapse:collapse"></td>
</tr>
<tr>
<td class="mailpoet_image mailpoet_padded_bottom mailpoet_padded_side" align="center" valign="top" style="border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<img src="http://newsletters.mailpoet.com/wp-content/uploads/2018/10/new_logo_orange.png" width="80" alt="new_logo_orange" style="height:auto;max-width:100%;-ms-interpolation-mode:bicubic;border:0;display:block;outline:none;text-align:center" />
</td>
</tr>
<tr>
<td class="mailpoet_spacer" height="26" valign="top" style="border-collapse:collapse"></td>
</tr>
<tr>
<td class="mailpoet_text mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;padding-top:0;border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<h1 style="text-align:center;padding:0;font-style:normal;font-weight:normal;margin:0 0 12px;color:#111111;font-family:'Trebuchet MS','Lucida Grande','Lucida Sans Unicode','Lucida Sans',Tahoma,sans-serif;font-size:40px;line-height:64px">
<strong><%= __('Your stats are in!') %></strong>
</h1>
</td>
</tr>
<tr>
<td class="mailpoet_text mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;padding-top:0;border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<h3 class="title" style="text-align:center;padding:0;font-style:normal;font-weight:normal;margin:0 0 6px;color:#333333;font-family:'Courier New',Courier,'Lucida Sans Typewriter','Lucida Typewriter',monospace;font-size:20px;line-height:32px">
<em><%= subject %></em>
</h3>
</td>
</tr>
<tr>
<td class="mailpoet_spacer" height="55" valign="top" style="border-collapse:collapse"></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="mailpoet_content-cols-two" align="left" style="border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tbody>
<tr>
<td align="center" style="font-size:0;border-collapse:collapse">
<!--[if mso]>
<table border="0" width="100%" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td width="330" valign="top">
<![endif]-->
<div style="display:inline-block; max-width:330px; vertical-align:top; width:100%;">
<table width="330" class="mailpoet_cols-two" border="0" cellpadding="0" cellspacing="0" align="left" style="width:100%;max-width:330px;border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;border-collapse:collapse">
<tbody>
<tr>
<td class="mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<div>
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tr>
<td class="mailpoet_button-container" style="text-align:center;border-collapse:collapse">
<a class="mailpoet_button" href="" style="display:inline-block;-webkit-text-size-adjust:none;mso-hide:all;text-decoration:none;text-align:center;background-color:#f0b849 ;border-color:#0074a2 ;border-width:0px ;border-radius:3px ;border-style:solid ;width:100px ;line-height:20px ;color:#ffffff ;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif ;font-size:10px ;font-weight:normal ">
GOOD
</a></td>
</tr>
</table>
</div>
</td>
</tr>
<tr>
<td class="mailpoet_text mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;padding-top:0;border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<h2 style="text-align:center;padding:0;font-style:normal;font-weight:normal;margin:0 0 12px;color:#222222;font-family:'Courier New',Courier,'Lucida Sans Typewriter','Lucida Typewriter',monospace;font-size:40px;line-height:64px">
<span style="color: #f0b849;">
<strong>29.8%</strong>
</span>
</h2>
</td>
</tr>
<tr>
<td class="mailpoet_text mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;padding-top:0;border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<table style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse" width="100%" cellpadding="0">
<tr>
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;text-align:center;border-collapse:collapse;color:#000000;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:16px;line-height:25.6px">
<span style="color: #f0b849;">
<%= __('open rate') %>
</span>
</td>
</tr></table>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso]>
</td>
<td width="330" valign="top">
<![endif]-->
<div style="display:inline-block; max-width:330px; vertical-align:top; width:100%;">
<table width="330" class="mailpoet_cols-two" border="0" cellpadding="0" cellspacing="0" align="left" style="width:100%;max-width:330px;border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;border-collapse:collapse">
<tbody>
<tr>
<td class="mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<div>
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tr>
<td class="mailpoet_button-container" style="text-align:center;border-collapse:collapse">
<a class="mailpoet_button" href="" style="display:inline-block;-webkit-text-size-adjust:none;mso-hide:all;text-decoration:none;text-align:center;background-color:#2993ab ;border-color:#0074a2 ;border-width:0px ;border-radius:3px ;border-style:solid ;width:100px ;line-height:20px ;color:#ffffff ;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif ;font-size:10px ;font-weight:normal ">
EXCELLENT
</a></td>
</tr>
</table>
</div>
</td>
</tr>
<tr>
<td class="mailpoet_text mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;padding-top:0;border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<h2 style="text-align:center;padding:0;font-style:normal;font-weight:normal;margin:0 0 12px;color:#222222;font-family:'Courier New',Courier,'Lucida Sans Typewriter','Lucida Typewriter',monospace;font-size:40px;line-height:64px">
<span style="color: #2993ab;">
3.1%
</span>
</h2>
</td>
</tr>
<tr>
<td class="mailpoet_text mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;padding-top:0;border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<table style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse" width="100%" cellpadding="0">
<tr>
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;text-align:center;border-collapse:collapse;color:#000000;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:16px;line-height:25.6px">
<span style="color: #2993ab;">
<%= __('click rate') %>
</span>
</td>
</tr></table>
</td>
</tr>
</tbody>
</table>
</div><!--[if mso]>
</td>
</tr>
</tbody>
</table>
<![endif]--></td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="mailpoet_content" align="center" style="border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tbody>
<tr>
<td style="padding-left:0;padding-right:0;border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" class="mailpoet_cols-one" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;border-collapse:collapse">
<tbody>
<tr>
<td class="mailpoet_divider" valign="top" style="padding:26.5px 20px 26.5px 20px;border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tr>
<td class="mailpoet_divider-cell" style="border-top-width:1px;border-top-style:solid;border-top-color:#e8e8e8;border-collapse:collapse">
</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="mailpoet_content" align="center" style="border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tbody>
<tr>
<td style="padding-left:0;padding-right:0;border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" class="mailpoet_cols-one" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;border-collapse:collapse">
<tbody>
<tr>
<td class="mailpoet_header_footer_padded mailpoet_header" style="line-height:38.4px;text-align:center ;color:#222222 ;font-family:'Trebuchet MS', 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', Tahoma, sans-serif ;font-size:24px ;border-collapse:collapse;padding:10px 20px">
<span style="font-weight: 600;">
<%= __('Most clicked link') %>
</span>
</td>
</tr>
<tr>
<td class="mailpoet_text mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;padding-top:0;border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<table style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse" width="100%" cellpadding="0">
<tr>
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;text-align:center;border-collapse:collapse;color:#000000;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:16px;line-height:25.6px">
<a href="<%= topLink %>" target="_blank" rel="noopener noreferrer" style="color:#008282;text-decoration:underline">
<%= topLink %>
</a>
</td>
</tr></table>
<table style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse" width="100%" cellpadding="0">
<tr>
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;text-align:center;border-collapse:collapse;color:#000000;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:16px;line-height:25.6px">
<span style="color: #000000;">
<%= __('%s unique clicks')|replace({'%s': topLinkClicks}) %>
</span>
</td>
</tr></table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="mailpoet_content" align="center" style="border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tbody>
<tr>
<td style="padding-left:0;padding-right:0;border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" class="mailpoet_cols-one" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;border-collapse:collapse">
<tbody>
<tr>
<td class="mailpoet_divider" valign="top" style="padding:6.5px 20px 6.5px 20px;border-collapse:collapse">
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tr>
<td class="mailpoet_divider-cell" style="border-top-width:1px;border-top-style:solid;border-top-color:#e8e8e8;border-collapse:collapse">
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="mailpoet_spacer" height="30" valign="top" style="border-collapse:collapse"></td>
</tr>
<tr>
<td class="mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<div>
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tr>
<td class="mailpoet_button-container" style="text-align:center;border-collapse:collapse">
<a class="mailpoet_button" href="https://account.mailpoet.com/premium" style="display:inline-block;-webkit-text-size-adjust:none;mso-hide:all;text-decoration:none;text-align:center;background-color:#fe5301 ;border-color:#0074a2 ;border-width:0px ;border-radius:3px ;border-style:solid ;width:288px ;line-height:50px ;color:#ffffff ;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif ;font-size:20px ;font-weight:normal ">
<%= __('View all stats') %>
</a></td>
</tr>
</table>
</div>
</td>
</tr>
<tr>
<td class="mailpoet_text mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;padding-top:0;border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<table style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse" width="100%" cellpadding="0">
<tr>
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;text-align:left;border-collapse:collapse;color:#000000;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:16px;line-height:25.6px">
<%= __('See more stats in the Premium version, like all the links that were clicked or which subscribers opened your emails. You can also create segments of subscribers by clicks and opens.') %>
</td>
</tr></table>
</td>
</tr>
<tr>
<td class="mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<div>
<table width="100%" cellpadding="0" cellspacing="0" border="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tr>
<td class="mailpoet_button-container" style="text-align:center;border-collapse:collapse">
<a class="mailpoet_button" href="#" style="display:inline-block;-webkit-text-size-adjust:none;mso-hide:all;text-decoration:none;text-align:center;background-color:#fe5301 ;border-color:#0074a2 ;border-width:0px ;border-radius:3px ;border-style:solid ;width:288px ;line-height:50px ;color:#ffffff ;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif ;font-size:20px ;font-weight:normal ">
<%= __('See Premium features') %>
</a></td>
</tr>
</table>
</div>
</td>
</tr>
<tr>
<td class="mailpoet_spacer" height="20" valign="top" style="border-collapse:collapse"></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="mailpoet_content-cols-two" align="left" style="border-collapse:collapse;background-color:#fe5301" bgcolor="#fe5301">
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse">
<tbody>
<tr>
<td align="center" style="font-size:0;border-collapse:collapse"><!--[if mso]>
<table border="0" width="100%" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td width="330" valign="top">
<![endif]--><div style="display:inline-block; max-width:330px; vertical-align:top; width:100%;">
<table width="330" class="mailpoet_cols-two" border="0" cellpadding="0" cellspacing="0" align="left" style="width:100%;max-width:330px;border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;border-collapse:collapse">
<tbody>
<tr>
<td class="mailpoet_spacer" bgcolor="#fe5301" height="24" valign="top" style="border-collapse:collapse"></td>
</tr>
<tr>
<td class="mailpoet_image mailpoet_padded_bottom mailpoet_padded_side" align="left" valign="top" style="border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<img src="http://newsletters.mailpoet.com/wp-content/uploads/2018/10/new_logo_white-300x95.png" width="130" alt="new_logo_white" style="height:auto;max-width:100%;-ms-interpolation-mode:bicubic;border:0;display:block;outline:none;text-align:center" />
</td>
</tr>
</tbody>
</table>
</div><!--[if mso]>
</td>
<td width="330" valign="top">
<![endif]--><div style="display:inline-block; max-width:330px; vertical-align:top; width:100%;">
<table width="330" class="mailpoet_cols-two" border="0" cellpadding="0" cellspacing="0" align="left" style="width:100%;max-width:330px;border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;table-layout:fixed;margin-left:auto;margin-right:auto;padding-left:0;padding-right:0;border-collapse:collapse">
<tbody>
<tr>
<td class="mailpoet_spacer" bgcolor="#fe5301" height="20" valign="top" style="border-collapse:collapse"></td>
</tr>
<tr>
<td class="mailpoet_text mailpoet_padded_bottom mailpoet_padded_side" valign="top" style="word-break:break-word;word-wrap:break-word;padding-top:0;border-collapse:collapse;padding-bottom:20px;padding-left:20px;padding-right:20px">
<table style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse" width="100%" cellpadding="0">
<tr>
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;text-align:right;border-collapse:collapse;color:#000000;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:16px;line-height:25.6px">
<span style="color: #ffffff;">
<a href="https://mailpoet.com/how-to-improve-open-rates" title="<%= __('How to Improve Open and Click Rates') %>" style="color:#008282;text-decoration:underline">
<%= __('How to improve my open rate?') %>
</a>
</span>
</td>
</tr></table>
<table style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse" width="100%" cellpadding="0">
<tr>
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;text-align:right;border-collapse:collapse;color:#000000;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:16px;line-height:25.6px">
<span style="color: #ffffff;"><a href="https://mailpoet.com/how-to-improve-click-rates" title="<%= __('How to Improve Open and Click Rates') %>" style="color:#008282;text-decoration:underline">
<%= __('And my click rate?') %>
</a></span>
</td>
</tr></table>
<table style="border-spacing:0;mso-table-lspace:0;mso-table-rspace:0;border-collapse:collapse" width="100%" cellpadding="0">
<tr>
<td class="mailpoet_paragraph" style="word-break:break-word;word-wrap:break-word;text-align:right;border-collapse:collapse;color:#000000;font-family:Arial,'Helvetica Neue',Helvetica,sans-serif;font-size:16px;line-height:25.6px">
<a href="<%= linkSettings %>" style="color:#008282;text-decoration:underline">
<%= __('Disable these emails') %>
</a>
</td>
</tr></table>
</td>
</tr>
</tbody>
</table>
</div><!--[if mso]>
</td>
</tr>
</tbody>
</table>
<![endif]--></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table><!--[if mso]>
</td>
</tr>
</table>
<![endif]--></td>
</tr>
</tbody>
</table>
</body>
</html>