Add deep links to email authorization notices
[MAILPOET-3830]
This commit is contained in:
@@ -26,15 +26,16 @@ type error = {
|
|||||||
message: string;
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getErrorMessage = (error: error | null): string => {
|
const getErrorMessage = (error: error | null, address: string | null): string => {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
return MailPoet.I18n.t('setFromAddressEmailUnknownError');
|
return MailPoet.I18n.t('setFromAddressEmailUnknownError');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error.error === 'unauthorized') {
|
if (error.error === 'unauthorized') {
|
||||||
|
const fromAddress = encodeURIComponent(address);
|
||||||
return MailPoet.I18n.t('setFromAddressEmailNotAuthorized').replace(
|
return MailPoet.I18n.t('setFromAddressEmailNotAuthorized').replace(
|
||||||
/\[link\](.*?)\[\/link\]/g,
|
/\[link\](.*?)\[\/link\]/g,
|
||||||
'<a href="https://account.mailpoet.com/authorization" target="_blank" rel="noopener noreferrer">$1</a>'
|
`<a href="https://account.mailpoet.com/authorization?email=${fromAddress}" target="_blank" rel="noopener noreferrer">$1</a>`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +144,7 @@ const SetFromAddressModal = ({ onRequestClose, setAuthorizedAddress }: Props) =>
|
|||||||
notices.success(getSuccessMessage(), { timeout: false });
|
notices.success(getSuccessMessage(), { timeout: false });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const error = e.errors && e.errors[0] ? e.errors[0] : null;
|
const error = e.errors && e.errors[0] ? e.errors[0] : null;
|
||||||
const message = getErrorMessage(error);
|
const message = getErrorMessage(error, address);
|
||||||
addressValidator.addError('saveError', { message });
|
addressValidator.addError('saveError', { message });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@@ -95,15 +95,16 @@ class NewsletterSend extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showInvalidFromAddressError = () => {
|
showInvalidFromAddressError = () => {
|
||||||
|
const fromAddress = this.state.item.sender_address;
|
||||||
let errorMessage = ReactStringReplace(
|
let errorMessage = ReactStringReplace(
|
||||||
MailPoet.I18n.t('newsletterInvalidFromAddress'),
|
MailPoet.I18n.t('newsletterInvalidFromAddress'),
|
||||||
'%$1s',
|
'%$1s',
|
||||||
() => this.state.item.sender_address
|
() => fromAddress
|
||||||
);
|
);
|
||||||
errorMessage = ReactStringReplace(
|
errorMessage = ReactStringReplace(
|
||||||
errorMessage,
|
errorMessage,
|
||||||
/\[link\](.*?)\[\/link\]/g,
|
/\[link\](.*?)\[\/link\]/g,
|
||||||
(match) => `<a href="https://account.mailpoet.com/authorization" target="_blank" rel="noopener noreferrer">${match}</a>`
|
(match) => `<a href="https://account.mailpoet.com/authorization?email=${encodeURIComponent(fromAddress)}" target="_blank" rel="noopener noreferrer">${match}</a>`
|
||||||
);
|
);
|
||||||
jQuery('#field_sender_address')
|
jQuery('#field_sender_address')
|
||||||
.parsley()
|
.parsley()
|
||||||
|
60
assets/js/src/sending-paused-notices-resume-button.jsx
Normal file
60
assets/js/src/sending-paused-notices-resume-button.jsx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import jQuery from 'jquery';
|
||||||
|
import MailPoet from 'mailpoet';
|
||||||
|
|
||||||
|
const loadAuthorizedEmailAddresses = async () => {
|
||||||
|
if (window.mailpoet_mta_method !== 'MailPoet') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const response = await MailPoet.Ajax.post({
|
||||||
|
api_version: window.mailpoet_api_version,
|
||||||
|
endpoint: 'mailer',
|
||||||
|
action: 'getAuthorizedEmailAddresses',
|
||||||
|
});
|
||||||
|
return response.data || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const isValidFromAddress = async (fromAddress) => {
|
||||||
|
if (window.mailpoet_mta_method !== 'MailPoet') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const addresses = await loadAuthorizedEmailAddresses();
|
||||||
|
return addresses.indexOf(fromAddress) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const resumeMailerSending = () => {
|
||||||
|
MailPoet.Ajax.post({
|
||||||
|
api_version: window.mailpoet_api_version,
|
||||||
|
endpoint: 'mailer',
|
||||||
|
action: 'resumeSending',
|
||||||
|
}).done(() => {
|
||||||
|
MailPoet.Notice.success(MailPoet.I18n.t('mailerSendingResumedNotice'));
|
||||||
|
window.mailpoet_listing.forceUpdate();
|
||||||
|
}).fail((response) => {
|
||||||
|
if (response.errors.length > 0) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
response.errors.map((error) => error.message),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const resumeSendingIfAuthorized = (fromAddress) => isValidFromAddress(fromAddress)
|
||||||
|
.then((valid) => {
|
||||||
|
if (!valid) {
|
||||||
|
MailPoet.Notice.error(
|
||||||
|
MailPoet.I18n.t('mailerSendingNotResumedUnauthorized'),
|
||||||
|
{ scroll: true }
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return resumeMailerSending();
|
||||||
|
});
|
||||||
|
|
||||||
|
// use jQuery since some of the targeted notices are added to the DOM using the old
|
||||||
|
// jQuery-based notice implementation which doesn't trigger pure-JS added listeners
|
||||||
|
jQuery(($) => {
|
||||||
|
$(document).on('click', '.notice .mailpoet-js-button-resume-sending', (e) => (
|
||||||
|
resumeSendingIfAuthorized(e.target.value)
|
||||||
|
));
|
||||||
|
});
|
@@ -15,3 +15,4 @@ import 'wizard/wizard.jsx'; // side effect - renders ReactDOM to document
|
|||||||
import 'experimental_features/experimental_features.jsx'; // side effect - renders ReactDOM to document
|
import 'experimental_features/experimental_features.jsx'; // side effect - renders ReactDOM to document
|
||||||
import 'logs/logs'; // side effect - renders ReactDOM to document
|
import 'logs/logs'; // side effect - renders ReactDOM to document
|
||||||
import 'sending-paused-notices-fix-button.tsx'; // side effect - renders ReactDOM to document
|
import 'sending-paused-notices-fix-button.tsx'; // side effect - renders ReactDOM to document
|
||||||
|
import 'sending-paused-notices-resume-button.jsx'; // side effect - executes on doc ready, adds events
|
||||||
|
@@ -35,21 +35,38 @@ class UnauthorizedEmailNotice {
|
|||||||
|
|
||||||
public function display($validationError) {
|
public function display($validationError) {
|
||||||
$message = $this->getMessageText($validationError);
|
$message = $this->getMessageText($validationError);
|
||||||
$message .= $this->getFixThisButton();
|
$message .= sprintf(
|
||||||
|
'<p>%s %s %s</p>',
|
||||||
|
$this->getAuthorizeEmailButton($validationError),
|
||||||
|
$this->getDifferentEmailButton(),
|
||||||
|
$this->getResumeSendingButton($validationError)
|
||||||
|
);
|
||||||
$extraClasses = 'mailpoet-js-error-unauthorized-emails-notice';
|
$extraClasses = 'mailpoet-js-error-unauthorized-emails-notice';
|
||||||
Notice::displayError($message, $extraClasses, self::OPTION_NAME, false, false);
|
Notice::displayError($message, $extraClasses, self::OPTION_NAME, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getMessageText($validationError) {
|
private function getMessageText($validationError) {
|
||||||
$text = $this->wp->_x('<b>Sending all of your emails has been paused</b> because your email address %s hasn’t been authorized yet.',
|
$text = $this->wp->_x('<b>Sending all of your emails has been paused</b> because your email address <b>%s</b> hasn’t been authorized yet.',
|
||||||
'Email addresses have to be authorized to be used to send emails. %s will be replaced by an email address.',
|
'Email addresses have to be authorized to be used to send emails. %s will be replaced by an email address.',
|
||||||
'mailpoet');
|
'mailpoet');
|
||||||
$message = str_replace('%s', EscapeHelper::escapeHtmlText($validationError['invalid_sender_address']), $text);
|
$message = str_replace('%s', EscapeHelper::escapeHtmlText($validationError['invalid_sender_address']), $text);
|
||||||
return "<p>$message</p>";
|
return "<p>$message</p>";
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getFixThisButton() {
|
private function getAuthorizeEmailButton($validationError) {
|
||||||
$button = '<button class="button button-primary mailpoet-js-button-fix-this">' . $this->wp->__('Fix this!', 'mailpoet') . '</button>';
|
$email = $this->wp->escAttr($validationError['invalid_sender_address']);
|
||||||
return "<p>$button</p>";
|
$button = '<a target="_blank" href="https://account.mailpoet.com/authorization?email=' . $email . '" class="button button-primary">' . $this->wp->__('Authorize this email address', 'mailpoet') . '</a>';
|
||||||
|
return $button;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getDifferentEmailButton() {
|
||||||
|
$button = '<button class="button button-secondary mailpoet-js-button-fix-this">' . $this->wp->__('Use a different email address', 'mailpoet') . '</button>';
|
||||||
|
return $button;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getResumeSendingButton($validationError) {
|
||||||
|
$email = $this->wp->escAttr($validationError['invalid_sender_address']);
|
||||||
|
$button = '<button class="button button-secondary mailpoet-js-button-resume-sending" value="' . $email . '">' . $this->wp->__('Resume sending', 'mailpoet') . '</button>';
|
||||||
|
return $button;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -88,6 +88,7 @@ jQuery('#adminmenu #toplevel_page_mailpoet-newsletters')
|
|||||||
'senderEmailAddressWarning2': _x('Use an address like %1$s for the Sender and put %2$s in the <em>Reply-to</em> field below.', 'In the last step, before sending a newsletter. URL: ?page=mailpoet-newsletters#/send/2'),
|
'senderEmailAddressWarning2': _x('Use an address like %1$s for the Sender and put %2$s in the <em>Reply-to</em> field below.', 'In the last step, before sending a newsletter. URL: ?page=mailpoet-newsletters#/send/2'),
|
||||||
'senderEmailAddressWarning3': _x('Read more.'),
|
'senderEmailAddressWarning3': _x('Read more.'),
|
||||||
'mailerSendingResumedNotice': __('Sending has been resumed.'),
|
'mailerSendingResumedNotice': __('Sending has been resumed.'),
|
||||||
|
'mailerSendingNotResumedUnauthorized': __('Failed to resume sending because the email address is unauthorized. Please authorize it and try again.'),
|
||||||
'dismissNotice': __('Dismiss this notice.'),
|
'dismissNotice': __('Dismiss this notice.'),
|
||||||
|
|
||||||
'subscribersLimitNoticeTitle': __('Congratulations, you now have more than [subscribersLimit] subscribers!'),
|
'subscribersLimitNoticeTitle': __('Congratulations, you now have more than [subscribersLimit] subscribers!'),
|
||||||
|
Reference in New Issue
Block a user