Display the unsubscribe reason to the user

[MAILPOET-2792]
This commit is contained in:
Pavel Dohnal
2020-06-18 11:08:41 +02:00
committed by Veljko V
parent 4e3b206734
commit 6e1cf96330
5 changed files with 92 additions and 20 deletions

View File

@@ -1,6 +1,7 @@
import React from 'react';
import { Link } from 'react-router-dom';
import MailPoet from 'mailpoet';
import moment from 'moment';
import PropTypes from 'prop-types';
import Form from 'form/form.jsx';
import ReactStringReplace from 'react-string-replace';
@@ -163,8 +164,40 @@ function beforeFormContent(subscriber) {
return undefined;
}
function afterFormContent() {
function afterFormContent(values) {
return (
<>
{values?.unsubscribes?.map((unsubscribe) => {
const date = moment(unsubscribe.createdAt.date).format('dddd MMMM Do YYYY at h:mm:ss a');
let message;
if (unsubscribe.source === 'admin') {
message = MailPoet.I18n.t('unsubcribedAdmin')
.replace('%$1d', date)
.replace('%$2d', unsubscribe.meta);
} else if (unsubscribe.source === 'manage') {
message = MailPoet.I18n.t('unsubcribedManage').replace('%$1d', date);
} else if (unsubscribe.source === 'newsletter') {
message = ReactStringReplace(
MailPoet.I18n.t('unsubcribedNewsletter').replace('%$1d', date),
/\[link\]/g,
(match, i) => (
<a
key={i}
href={`admin.php?page=mailpoet-newsletter-editor&id=${unsubscribe.newsletterId}`}
>
{ unsubscribe.newsletterSubject }
</a>
)
);
} else {
message = MailPoet.I18n.t('unsubcribedUnknown').replace('%$1d', date);
}
return (
<p className="description" key={message}>
{message}
</p>
);
})}
<p className="description">
<strong>
{ MailPoet.I18n.t('tip') }
@@ -172,6 +205,7 @@ function afterFormContent() {
{' '}
{ MailPoet.I18n.t('customFieldsTip') }
</p>
</>
);
}

View File

@@ -6,6 +6,7 @@ use MailPoet\API\JSON\Endpoint as APIEndpoint;
use MailPoet\API\JSON\Error as APIError;
use MailPoet\API\JSON\Response as APIResponse;
use MailPoet\Config\AccessControl;
use MailPoet\Entities\NewsletterEntity;
use MailPoet\Entities\StatisticsUnsubscribeEntity;
use MailPoet\Entities\SubscriberEntity;
use MailPoet\Form\Util\FieldNameObfuscator;
@@ -19,6 +20,7 @@ use MailPoet\Newsletter\Scheduler\WelcomeScheduler;
use MailPoet\Segments\BulkAction;
use MailPoet\Segments\SubscribersListings;
use MailPoet\Settings\SettingsController;
use MailPoet\Statistics\StatisticsUnsubscribesRepository;
use MailPoet\Statistics\Track\Unsubscribes;
use MailPoet\Subscribers\ConfirmationEmailMailer;
use MailPoet\Subscribers\RequiredCustomFieldValidator;
@@ -77,6 +79,9 @@ class Subscribers extends APIEndpoint {
/** @var Unsubscribes */
private $unsubscribesTracker;
/** @var StatisticsUnsubscribesRepository */
private $statisticsUnsubscribesRepository;
public function __construct(
Listing\BulkActionController $bulkActionController,
SubscribersListings $subscribersListings,
@@ -90,6 +95,7 @@ class Subscribers extends APIEndpoint {
ConfirmationEmailMailer $confirmationEmailMailer,
SubscriptionUrlFactory $subscriptionUrlFactory,
Unsubscribes $unsubscribesTracker,
StatisticsUnsubscribesRepository $statisticsUnsubscribesRepository,
FieldNameObfuscator $fieldNameObfuscator
) {
$this->bulkActionController = $bulkActionController;
@@ -105,6 +111,7 @@ class Subscribers extends APIEndpoint {
$this->subscriptionUrlFactory = $subscriptionUrlFactory;
$this->fieldNameObfuscator = $fieldNameObfuscator;
$this->unsubscribesTracker = $unsubscribesTracker;
$this->statisticsUnsubscribesRepository = $statisticsUnsubscribesRepository;
}
public function get($data = []) {
@@ -115,12 +122,30 @@ class Subscribers extends APIEndpoint {
APIError::NOT_FOUND => WPFunctions::get()->__('This subscriber does not exist.', 'mailpoet'),
]);
} else {
return $this->successResponse(
$subscriber
$unsubscribes = $this->statisticsUnsubscribesRepository->findBy([
'subscriberId' => $id,
], [
'createdAt' => 'desc',
]);
$result = $subscriber
->withCustomFields()
->withSubscriptions()
->asArray()
);
->asArray();
$result['unsubscribes'] = [];
foreach ($unsubscribes as $unsubscribe) {
$mapped = [
'source' => $unsubscribe->getSource(),
'meta' => $unsubscribe->getMeta(),
'createdAt' => $unsubscribe->getCreatedAt(),
];
$newsletter = $unsubscribe->getNewsletter();
if ($newsletter instanceof NewsletterEntity) {
$mapped['newsletterId'] = $newsletter->getId();
$mapped['newsletterSubject'] = $newsletter->getSubject();
}
$result['unsubscribes'][] = $mapped;
}
return $this->successResponse($result);
}
}

View File

@@ -98,4 +98,11 @@ class StatisticsUnsubscribeEntity {
public function setMeta(string $meta) {
$this->meta = $meta;
}
/**
* @return string|null
*/
public function getMeta() {
return $this->meta;
}
}

View File

@@ -22,6 +22,7 @@ use MailPoet\Models\SubscriberSegment;
use MailPoet\Segments\SubscribersListings;
use MailPoet\Settings\SettingsController;
use MailPoet\Settings\SettingsRepository;
use MailPoet\Statistics\StatisticsUnsubscribesRepository;
use MailPoet\Statistics\Track\Unsubscribes;
use MailPoet\Subscribers\ConfirmationEmailMailer;
use MailPoet\Subscribers\LinkTokens;
@@ -74,6 +75,7 @@ class SubscribersTest extends \MailPoetTest {
$container->get(ConfirmationEmailMailer::class),
new SubscriptionUrlFactory($wp, $settings, new LinkTokens),
$container->get(Unsubscribes::class),
$container->get(StatisticsUnsubscribesRepository::class),
$obfuscator
);
$this->obfuscatedEmail = $obfuscator->obfuscate('email');
@@ -135,12 +137,11 @@ class SubscribersTest extends \MailPoetTest {
$response = $this->endpoint->get(['id' => $this->subscriber1->id]);
expect($response->status)->equals(APIResponse::STATUS_OK);
expect($response->data)->equals(
Subscriber::findOne($this->subscriber1->id)
->withCustomFields()
->withSubscriptions()
->asArray()
);
expect($response->data['id'])->equals($this->subscriber1->id);
expect($response->data['first_name'])->equals($this->subscriber1->first_name);
expect($response->data['email'])->equals($this->subscriber1->email);
expect($response->data['unsubscribes'])->equals([]);
expect($response->data['subscriptions'])->equals([]);
}
public function testItCanSaveANewSubscriber() {

View File

@@ -89,6 +89,11 @@
'subscriberAdded': __('Subscriber was added successfully!'),
'welcomeEmailTip': __('This subscriber will receive Welcome Emails if any are active for your lists.'),
'unsubcribedNewsletter': __('Unsubscribed at %$1d, from newsletter [link].'),
'unsubcribedManage': __('Unsubscribed at %$1d, using the Manage my Subscription page.'),
'unsubcribedAdmin': __('Unsubscribed at %$1d, by admin "%$2d".'),
'unsubcribedUnknown': __('Unsubscribed at %$1d, for an unknown reason.'),
'subscriber': __('Subscriber'),
'status': __('Status'),
'lists': __('Lists'),