diff --git a/mailpoet/assets/js/src/public.jsx b/mailpoet/assets/js/src/public.jsx
index 9fd8d810da..a4437c2dd7 100644
--- a/mailpoet/assets/js/src/public.jsx
+++ b/mailpoet/assets/js/src/public.jsx
@@ -77,6 +77,76 @@ jQuery(($) => {
});
}
+ function submitSubscribeForm(form, formData, parsley) {
+ form.addClass('mailpoet_form_sending');
+ // ajax request
+ MailPoet.Ajax.post({
+ url: window.MailPoetForm.ajax_url,
+ token: formData.token,
+ api_version: formData.api_version,
+ endpoint: 'subscribers',
+ action: 'subscribe',
+ data: formData.data,
+ })
+ .fail((response) => {
+ if (
+ response.meta !== undefined &&
+ response.meta.redirect_url !== undefined
+ ) {
+ // go to page
+ window.top.location.href = response.meta.redirect_url;
+ } else {
+ if (response.meta && response.meta.refresh_captcha) {
+ updateCaptcha();
+ }
+ form
+ .find('.mailpoet_validate_error')
+ .html(response.errors.map((error) => error.message).join('
'))
+ .show();
+ }
+ })
+ .done((response) => {
+ if (window.grecaptcha && formData.recaptcha) {
+ window.grecaptcha.reset(formData.recaptcha);
+ }
+ return response;
+ })
+ .done((response) => {
+ // successfully subscribed
+ if (
+ response.meta !== undefined &&
+ response.meta.redirect_url !== undefined
+ ) {
+ setFormCookieAfterSubscription(form);
+ // go to page
+ window.location.href = response.meta.redirect_url;
+ } else {
+ displaySuccessMessage(form);
+ }
+
+ // reset form
+ form.trigger('reset');
+ // reset validation
+ parsley.reset();
+ // reset captcha
+ if (window.grecaptcha && formData.recaptcha) {
+ window.grecaptcha.reset(formData.recaptcha);
+ }
+
+ // resize iframe
+ if (
+ window.frameElement !== null &&
+ MailPoet !== undefined &&
+ MailPoet.Iframe
+ ) {
+ MailPoet.Iframe.autoSize(window.frameElement);
+ }
+ })
+ .always(() => {
+ form.removeClass('mailpoet_form_sending');
+ });
+ }
+
function renderCaptcha(element, iteration) {
if (!window.recaptcha || !window.grecaptcha.ready) {
if (iteration < 20) {
@@ -85,12 +155,31 @@ jQuery(($) => {
return;
}
const recaptcha = $(element);
+ const form = $(recaptcha).parent('form');
const sitekey = recaptcha.attr('data-sitekey');
+ let size = recaptcha.attr('data-size');
+
+ // Users should not be able to change the size if it is equal to 'invisible' as this would
+ // change the type of the ReCaptcha.
+ if (size !== 'invisible') {
+ size = Hooks.applyFilters('mailpoet_re_captcha_size', 'compact');
+ }
+
const container = recaptcha.find('> .mailpoet_recaptcha_container').get(0);
const field = recaptcha.find('> .mailpoet_recaptcha_field');
if (sitekey) {
- const size = Hooks.applyFilters('mailpoet_re_captcha_size', 'compact');
- const widgetId = window.grecaptcha.render(container, { sitekey, size });
+ const params = { sitekey, size };
+
+ if (size === 'invisible') {
+ params.callback = function invisibleReCaptchaCallback(token) {
+ const formData = form.mailpoetSerializeObject() || {};
+ formData.data.recaptcha = token;
+
+ submitSubscribeForm(form, formData, form.parsley());
+ };
+ }
+
+ const widgetId = window.grecaptcha.render(container, params);
field.val(widgetId);
}
}
@@ -299,88 +388,36 @@ jQuery(($) => {
}, 2500);
return false;
}
- const formData = form.mailpoetSerializeObject() || {};
+
// check if we're on the same domain
if (isSameDomain(window.MailPoetForm.ajax_url) === false) {
// non ajax post request
return true;
}
+ const formData = form.mailpoetSerializeObject() || {};
+ const size = form.children('.mailpoet_recaptcha').attr('data-size');
+
if (window.grecaptcha && formData.recaptcha) {
- formData.data.recaptcha = window.grecaptcha.getResponse(
- formData.recaptcha,
- );
+ // The API for the invisible and checkbox ReCaptchas is slightly different. For the
+ // former, we need to call execute() and then the ReCaptcha API calls the callback set
+ // inside renderCaptcha() with a token if the captcha was solved successfully. The
+ // callback then calls submitSubscribeForm() with the token. For the latter, we get the
+ // token here after calling getResponse() and then we can call submitSubscribeForm()
+ // directly.
+ if (size === 'invisible') {
+ window.grecaptcha.execute();
+ } else {
+ formData.data.recaptcha = window.grecaptcha.getResponse(
+ formData.recaptcha,
+ );
+ }
}
- form.addClass('mailpoet_form_sending');
- // ajax request
- MailPoet.Ajax.post({
- url: window.MailPoetForm.ajax_url,
- token: formData.token,
- api_version: formData.api_version,
- endpoint: 'subscribers',
- action: 'subscribe',
- data: formData.data,
- })
- .fail((response) => {
- if (
- response.meta !== undefined &&
- response.meta.redirect_url !== undefined
- ) {
- // go to page
- window.top.location.href = response.meta.redirect_url;
- } else {
- if (response.meta && response.meta.refresh_captcha) {
- updateCaptcha();
- }
- form
- .find('.mailpoet_validate_error')
- .html(
- response.errors.map((error) => error.message).join('
'),
- )
- .show();
- }
- })
- .done((response) => {
- if (window.grecaptcha && formData.recaptcha) {
- window.grecaptcha.reset(formData.recaptcha);
- }
- return response;
- })
- .done((response) => {
- // successfully subscribed
- if (
- response.meta !== undefined &&
- response.meta.redirect_url !== undefined
- ) {
- setFormCookieAfterSubscription(form);
- // go to page
- window.location.href = response.meta.redirect_url;
- } else {
- displaySuccessMessage(form);
- }
+ if (size !== 'invisible') {
+ submitSubscribeForm(form, formData, parsley);
+ }
- // reset form
- form.trigger('reset');
- // reset validation
- parsley.reset();
- // reset captcha
- if (window.grecaptcha && formData.recaptcha) {
- window.grecaptcha.reset(formData.recaptcha);
- }
-
- // resize iframe
- if (
- window.frameElement !== null &&
- MailPoet !== undefined &&
- MailPoet.Iframe
- ) {
- MailPoet.Iframe.autoSize(window.frameElement);
- }
- })
- .always(() => {
- form.removeClass('mailpoet_form_sending');
- });
return false;
});
});
diff --git a/mailpoet/lib/Form/AssetsController.php b/mailpoet/lib/Form/AssetsController.php
index 94318b8b1c..5ebf22f868 100644
--- a/mailpoet/lib/Form/AssetsController.php
+++ b/mailpoet/lib/Form/AssetsController.php
@@ -33,14 +33,14 @@ class AssetsController {
public function printScripts() {
ob_start();
$captcha = $this->settings->get('captcha');
- if (!empty($captcha['type']) && $captcha['type'] === Captcha::TYPE_RECAPTCHA) {
+ if (!empty($captcha['type']) && Captcha::isReCaptcha($captcha['type'])) {
echo '';
}
$this->wp->wpPrintScripts('jquery');
$this->wp->wpPrintScripts('mailpoet_vendor');
$this->wp->wpPrintScripts('mailpoet_public');
-
+
$scripts = ob_get_contents();
ob_end_clean();
if ($scripts === false) {
@@ -62,7 +62,7 @@ class AssetsController {
public function setupFrontEndDependencies() {
$captcha = $this->settings->get('captcha');
- if (!empty($captcha['type']) && $captcha['type'] === Captcha::TYPE_RECAPTCHA) {
+ if (!empty($captcha['type']) && Captcha::isRecaptcha($captcha['type'])) {
$this->wp->wpEnqueueScript(
'mailpoet_recaptcha',
self::RECAPTCHA_API_URL
diff --git a/mailpoet/lib/Form/Renderer.php b/mailpoet/lib/Form/Renderer.php
index bd76dbdfa4..d5d3a9fa3c 100644
--- a/mailpoet/lib/Form/Renderer.php
+++ b/mailpoet/lib/Form/Renderer.php
@@ -70,7 +70,7 @@ class Renderer {
if (
$captchaEnabled
&& $block['type'] === FormEntity::SUBMIT_BLOCK_TYPE
- && $this->settings->get('captcha.type') === Captcha::TYPE_RECAPTCHA
+ && Captcha::isRecaptcha($this->settings->get('captcha.type'))
) {
$html .= $this->renderReCaptcha();
}
@@ -89,8 +89,15 @@ class Renderer {
}
private function renderReCaptcha(): string {
- $siteKey = $this->settings->get('captcha.recaptcha_site_token');
- return '