Compare commits

...

2 Commits

Author SHA1 Message Date
600c5ad4af Release 4.41.2 2024-01-11 10:46:32 -06:00
fc8592c12c Display different notices before Feb 1st
MAILPOET-5819
2024-01-11 10:40:38 -06:00
5 changed files with 87 additions and 22 deletions

View File

@ -10,6 +10,7 @@ use MailPoet\Util\FreeDomains;
use MailPoet\Util\Helpers;
use MailPoet\Util\License\Features\Subscribers;
use MailPoet\WP\Notice;
use MailPoetVendor\Carbon\Carbon;
class SenderDomainAuthenticationNotices {
@ -19,6 +20,8 @@ class SenderDomainAuthenticationNotices {
const FREE_MAIL_KB_URL = 'https://kb.mailpoet.com/article/259-your-from-address-cannot-be-yahoo-com-gmail-com-outlook-com';
const SPF_DKIM_DMARC_KB_URL = 'https://kb.mailpoet.com/article/295-spf-dkim-dmarc';
const ENFORCEMENT_START_TIME = '2024-02-01 00:00:00 UTC';
const INSTALLED_AFTER_NEW_RESTRICTIONS_OPTION = 'installed_after_new_domain_restrictions';
private SettingsController $settingsController;
@ -61,6 +64,11 @@ class SenderDomainAuthenticationNotices {
return $this->freeDomains->isEmailOnFreeDomain($this->getDefaultFromDomain());
}
// TODO: Remove after the enforcement date has passed
public function isEnforcementOfNewRestrictionsInEffect(): bool {
return Carbon::now() >= Carbon::parse(self::ENFORCEMENT_START_TIME);
}
public function isNewUser(): bool {
$installedVersion = $this->settingsController->get('version');
@ -110,6 +118,9 @@ class SenderDomainAuthenticationNotices {
}
public function isErrorStyle(): bool {
if (!$this->isEnforcementOfNewRestrictionsInEffect()) {
return false;
}
if (
$this->subscribersFeatures->getSubscribersCount() < self::UPPER_LIMIT
|| $this->isPartiallyVerified()
@ -125,6 +136,17 @@ class SenderDomainAuthenticationNotices {
}
public function getNoticeContentForFreeMailUsers(int $contactCount): string {
if (!$this->isEnforcementOfNewRestrictionsInEffect()) {
// translators: %1$s is the domain of the user's default from address, %2$s is a rewritten version of their default from address, %3$s is HTML for an 'update sender' button, and %4$s is HTML for a Learn More button
return sprintf(__("<strong>Update your sender email address to a branded domain by February 1st, 2024 to continue sending your campaigns.</strong>
<span>Starting on February 1st, 2024, MailPoet will no longer be able to send from email addresses on shared 3rd party domains like <strong>%1\$s</strong>. Please change your campaigns to send from an email address on your site's branded domain. Your emails will temporarily be sent from <strong>%2\$s</strong>.</span> <p>%3\$s &nbsp; %4\$s</p>", 'mailpoet'),
"@" . $this->getDefaultFromDomain(),
$this->authorizedSenderDomainController->getRewrittenEmailAddress($this->getDefaultFromAddress()),
$this->getUpdateSenderButton(),
$this->getLearnMoreAboutFreeMailButton()
);
}
if ($contactCount <= self::UPPER_LIMIT) {
// translators: %1$s is the domain of the user's default from address, %2$s is a rewritten version of their default from address, %3$s is HTML for an 'update sender' button, and %4$s is HTML for a Learn More button
return sprintf(__("<strong>Update your sender email address to a branded domain to continue sending your campaigns.</strong>
@ -147,7 +169,7 @@ class SenderDomainAuthenticationNotices {
}
public function getNoticeContentForBrandedDomainUsers(bool $isPartiallyVerified, int $contactCount): string {
if ($isPartiallyVerified || $contactCount <= self::LOWER_LIMIT) {
if (!$this->isEnforcementOfNewRestrictionsInEffect() || $isPartiallyVerified || $contactCount <= self::LOWER_LIMIT) {
// translators: %1$s is HTML for an 'authenticate domain' button, %2$s is HTML for a Learn More button
return sprintf(__("<strong>Authenticate your sender domain to improve email delivery rates.</strong>
<span>Major mailbox providers require you to authenticate your sender domain to confirm you sent the emails, and may place unauthenticated emails in the \"Spam\" folder. Please authenticate your sender domain to ensure your marketing campaigns are compliant and will reach your contacts.</span><p>%1\$s &nbsp; %2\$s</p>", 'mailpoet'),

View File

@ -2,7 +2,7 @@
/*
* Plugin Name: MailPoet
* Version: 4.41.1
* Version: 4.41.2
* Plugin URI: https://www.mailpoet.com
* Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
* Author: MailPoet
@ -20,7 +20,7 @@
*/
$mailpoetPlugin = [
'version' => '4.41.1',
'version' => '4.41.2',
'filename' => __FILE__,
'path' => dirname(__FILE__),
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',

View File

@ -3,7 +3,7 @@ Contributors: mailpoet, woocommerce, automattic
Tags: email, email marketing, post notification, woocommerce emails, email automation, newsletter, newsletter builder, newsletter subscribers
Requires at least: 6.3
Tested up to: 6.4
Stable tag: 4.41.1
Stable tag: 4.41.2
Requires PHP: 7.4
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html
@ -219,6 +219,9 @@ Check our [Knowledge Base](https://kb.mailpoet.com) or contact us through our [s
== Changelog ==
= 4.41.2 - 2024-01-11 =
* Improved: notices in the banners now indicate that the new sending rules will be enforced on February 1st.
= 4.41.1 - 2024-01-10 =
* Fixed: Partially verified domains could not be re-verified

View File

@ -8,6 +8,7 @@ use MailPoet\Test\DataFactories\Newsletter;
use MailPoet\Test\DataFactories\StatisticsNewsletters;
use MailPoet\Test\DataFactories\Subscriber;
use MailPoet\Util\Notices\SenderDomainAuthenticationNotices;
use MailPoetVendor\Carbon\Carbon;
class SenderDomainAuthenticationNoticesTest extends \MailPoetTest {
/** @var SenderDomainAuthenticationNotices */
@ -63,10 +64,18 @@ class SenderDomainAuthenticationNoticesTest extends \MailPoetTest {
'address' => $email,
]);
$rewrittenEmail = $this->authorizedSenderDomainController->getRewrittenEmailAddress($email);
$message = $this->notice->getNoticeContentForFreeMailUsers(1001);
$this->assertStringContainsString('Your newsletters and post notifications have been paused. Update your sender email address to a branded domain to continue sending your campaigns', $message);
$this->assertStringContainsString(sprintf('Your marketing automations and transactional emails will temporarily be sent from <strong>%s</strong>', $rewrittenEmail), $message);
$this->assertStringContainsString('Update sender email', $message);
Carbon::setTestNow(Carbon::parse('2024-01-31 00:00:00 UTC'));
$beforeRestrictionsInEffectMessage = $this->notice->getNoticeContentForFreeMailUsers(999);
$this->assertStringContainsString('Update your sender email address to a branded domain by February 1st, 2024 to continue sending your campaigns.', $beforeRestrictionsInEffectMessage);
$this->assertStringContainsString(sprintf('Your emails will temporarily be sent from <strong>%s</strong>', $rewrittenEmail), $beforeRestrictionsInEffectMessage);
$this->assertStringContainsString('Update sender email', $beforeRestrictionsInEffectMessage);
Carbon::setTestNow(Carbon::parse('2024-02-01 00:00:00 UTC'));
$afterRestrictionsInEffectMessage = $this->notice->getNoticeContentForFreeMailUsers(1001);
$this->assertStringContainsString('Your newsletters and post notifications have been paused. Update your sender email address to a branded domain to continue sending your campaigns', $afterRestrictionsInEffectMessage);
$this->assertStringContainsString(sprintf('Your marketing automations and transactional emails will temporarily be sent from <strong>%s</strong>', $rewrittenEmail), $afterRestrictionsInEffectMessage);
$this->assertStringContainsString('Update sender email', $afterRestrictionsInEffectMessage);
}
public function testItRetrievesAppropriateMessageForFreeMailUsersWithLessThan1000Contacts(): void {
@ -76,10 +85,18 @@ class SenderDomainAuthenticationNoticesTest extends \MailPoetTest {
'address' => $email,
]);
$rewrittenEmail = $this->authorizedSenderDomainController->getRewrittenEmailAddress($email);
$message = $this->notice->getNoticeContentForFreeMailUsers(999);
$this->assertStringContainsString('Update your sender email address to a branded domain to continue sending your campaigns', $message);
$this->assertStringContainsString(sprintf('Your existing scheduled and active emails will temporarily be sent from <strong>%s</strong>', $rewrittenEmail), $message);
$this->assertStringContainsString('Update sender email', $message);
Carbon::setTestNow(Carbon::parse('2024-01-31 00:00:00 UTC'));
$beforeRestrictionsInEffectMessage = $this->notice->getNoticeContentForFreeMailUsers(999);
$this->assertStringContainsString('Update your sender email address to a branded domain by February 1st, 2024 to continue sending your campaigns.', $beforeRestrictionsInEffectMessage);
$this->assertStringContainsString(sprintf('Your emails will temporarily be sent from <strong>%s</strong>', $rewrittenEmail), $beforeRestrictionsInEffectMessage);
$this->assertStringContainsString('Update sender email', $beforeRestrictionsInEffectMessage);
Carbon::setTestNow(Carbon::parse('2024-02-01 00:00:00 UTC'));
$afterRestrictionsInEffectMessage = $this->notice->getNoticeContentForFreeMailUsers(999);
$this->assertStringContainsString('Update your sender email address to a branded domain to continue sending your campaigns', $afterRestrictionsInEffectMessage);
$this->assertStringContainsString(sprintf('Your existing scheduled and active emails will temporarily be sent from <strong>%s</strong>', $rewrittenEmail), $afterRestrictionsInEffectMessage);
$this->assertStringContainsString('Update sender email', $afterRestrictionsInEffectMessage);
}
public function testItRetrievesAppropriateMessageForBrandedDomainsWithMoreThan1000Contacts(): void {
@ -89,11 +106,18 @@ class SenderDomainAuthenticationNoticesTest extends \MailPoetTest {
'address' => $email,
]);
$rewrittenEmail = $this->authorizedSenderDomainController->getRewrittenEmailAddress($email);
$message = $this->notice->getNoticeContentForBrandedDomainUsers(false, 1001);
$this->assertStringContainsString('Your newsletters and post notifications have been paused. Authenticate your sender domain to continue sending.', $message);
$this->assertStringContainsString('Your marketing automations and transactional emails will temporarily be sent from', $message);
$this->assertStringContainsString($rewrittenEmail, $message);
$this->assertStringContainsString('Authenticate domain', $message);
Carbon::setTestNow(Carbon::parse('2024-01-31 00:00:00 UTC'));
$beforeRestrictionsInEffectMessage = $this->notice->getNoticeContentForBrandedDomainUsers(false, 1001);
$this->assertStringContainsString('Authenticate your sender domain to improve email delivery rates.', $beforeRestrictionsInEffectMessage);
$this->assertStringContainsString('Please authenticate your sender domain to ensure your marketing campaigns are compliant and will reach your contacts', $beforeRestrictionsInEffectMessage);
Carbon::setTestNow(Carbon::parse('2024-02-01 00:00:00 UTC'));
$afterRestrictionsInEffectMessage = $this->notice->getNoticeContentForBrandedDomainUsers(false, 1001);
$this->assertStringContainsString('Your newsletters and post notifications have been paused. Authenticate your sender domain to continue sending.', $afterRestrictionsInEffectMessage);
$this->assertStringContainsString('Your marketing automations and transactional emails will temporarily be sent from', $afterRestrictionsInEffectMessage);
$this->assertStringContainsString($rewrittenEmail, $afterRestrictionsInEffectMessage);
$this->assertStringContainsString('Authenticate domain', $afterRestrictionsInEffectMessage);
}
public function testItRetrievesAppropriateMessageForBrandedDomainsWithLessThan1000Contacts(): void {
@ -103,11 +127,18 @@ class SenderDomainAuthenticationNoticesTest extends \MailPoetTest {
'address' => $email,
]);
$rewrittenEmail = $this->authorizedSenderDomainController->getRewrittenEmailAddress($email);
$message = $this->notice->getNoticeContentForBrandedDomainUsers(false, 999);
$this->assertStringContainsString('Authenticate your sender domain to send new emails.', $message);
$this->assertStringContainsString('Your existing scheduled and active emails will temporarily be sent from', $message);
$this->assertStringContainsString($rewrittenEmail, $message);
$this->assertStringContainsString('Authenticate domain', $message);
Carbon::setTestNow(Carbon::parse('2024-01-31 00:00:00 UTC'));
$beforeRestrictionsInEffectMessage = $this->notice->getNoticeContentForBrandedDomainUsers(false, 1001);
$this->assertStringContainsString('Authenticate your sender domain to improve email delivery rates.', $beforeRestrictionsInEffectMessage);
$this->assertStringContainsString('Please authenticate your sender domain to ensure your marketing campaigns are compliant and will reach your contacts', $beforeRestrictionsInEffectMessage);
Carbon::setTestNow(Carbon::parse('2024-02-01 00:00:00 UTC'));
$afterRestrictionsInEffectMessage = $this->notice->getNoticeContentForBrandedDomainUsers(false, 999);
$this->assertStringContainsString('Authenticate your sender domain to send new emails.', $afterRestrictionsInEffectMessage);
$this->assertStringContainsString('Your existing scheduled and active emails will temporarily be sent from', $afterRestrictionsInEffectMessage);
$this->assertStringContainsString($rewrittenEmail, $afterRestrictionsInEffectMessage);
$this->assertStringContainsString('Authenticate domain', $afterRestrictionsInEffectMessage);
}
public function testItRetrievesAppropriateMessageForBrandedDomainsWithLessThan500Contacts(): void {
@ -154,4 +185,11 @@ class SenderDomainAuthenticationNoticesTest extends \MailPoetTest {
(new StatisticsNewsletters((new Newsletter())->withSendingQueue()->create(), (new Subscriber())->create()))->create();
$this->assertFalse($this->notice->isNewUser());
}
public function testItKnowsWhenNewRestrictionsStartGettingEnforced(): void {
Carbon::setTestNow(Carbon::parse('2024-01-31 00:00:00 UTC'));
$this->assertFalse($this->notice->isEnforcementOfNewRestrictionsInEffect());
Carbon::setTestNow(Carbon::parse('2024-02-01 00:00:01 UTC'));
$this->assertTrue($this->notice->isEnforcementOfNewRestrictionsInEffect());
}
}

View File

@ -238,6 +238,8 @@ abstract class MailPoetTest extends \Codeception\TestCase\Test { // phpcs:ignore
public function _after() {
parent::_after();
$this->tester->cleanup();
// Reset any overrides
Carbon::setTestNow();
}
}