Display the unsubscribe reason to the user
[MAILPOET-2792]
This commit is contained in:
@@ -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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -98,4 +98,11 @@ class StatisticsUnsubscribeEntity {
|
||||
public function setMeta(string $meta) {
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMeta() {
|
||||
return $this->meta;
|
||||
}
|
||||
}
|
||||
|
@@ -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() {
|
||||
|
@@ -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'),
|
||||
|
Reference in New Issue
Block a user