Add captcha page [MAILPOET-2015]
This commit is contained in:
@ -44,6 +44,15 @@
|
|||||||
margin: 0 7px;
|
margin: 0 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mailpoet_captcha_form {
|
||||||
|
.mailpoet_validate_success { color: #468847; }
|
||||||
|
.mailpoet_validate_error { color: #b94a48; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet_captcha_update {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes mailpoet-bouncedelay {
|
@keyframes mailpoet-bouncedelay {
|
||||||
0%,
|
0%,
|
||||||
80%,
|
80%,
|
||||||
|
@ -175,6 +175,7 @@ class Populator {
|
|||||||
'unsubscribe' => $mailpoet_page_id,
|
'unsubscribe' => $mailpoet_page_id,
|
||||||
'manage' => $mailpoet_page_id,
|
'manage' => $mailpoet_page_id,
|
||||||
'confirmation' => $mailpoet_page_id,
|
'confirmation' => $mailpoet_page_id,
|
||||||
|
'captcha' => $mailpoet_page_id,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,8 @@ abstract class Base {
|
|||||||
protected static function getFieldName($block = []) {
|
protected static function getFieldName($block = []) {
|
||||||
if ((int)$block['id'] > 0) {
|
if ((int)$block['id'] > 0) {
|
||||||
return 'cf_' . $block['id'];
|
return 'cf_' . $block['id'];
|
||||||
|
} elseif (isset($block['params']['obfuscate']) && !$block['params']['obfuscate']) {
|
||||||
|
return $block['id'];
|
||||||
} else {
|
} else {
|
||||||
$obfuscator = new FieldNameObfuscator();
|
$obfuscator = new FieldNameObfuscator();
|
||||||
return $obfuscator->obfuscate($block['id']);//obfuscate field name for spambots
|
return $obfuscator->obfuscate($block['id']);//obfuscate field name for spambots
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
namespace MailPoet\Form;
|
namespace MailPoet\Form;
|
||||||
|
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
|
use MailPoet\Subscription\Captcha;
|
||||||
|
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
|
|
||||||
@ -50,8 +51,8 @@ class Renderer {
|
|||||||
'<label class="mailpoet_hp_email_label">' . WPFunctions::get()->__('Please leave this field empty', 'mailpoet') . '<input type="email" name="data[email]"></label>' :
|
'<label class="mailpoet_hp_email_label">' . WPFunctions::get()->__('Please leave this field empty', 'mailpoet') . '<input type="email" name="data[email]"></label>' :
|
||||||
'';
|
'';
|
||||||
foreach ($blocks as $key => $block) {
|
foreach ($blocks as $key => $block) {
|
||||||
if ($block['type'] == 'submit' && $settings->get('re_captcha.enabled')) {
|
if ($block['type'] == 'submit' && $settings->get('captcha.type') === Captcha::TYPE_RECAPTCHA) {
|
||||||
$site_key = $settings->get('re_captcha.site_token');
|
$site_key = $settings->get('captcha.recaptcha_site_token');
|
||||||
$html .= '<div class="mailpoet_recaptcha" data-sitekey="' . $site_key . '">
|
$html .= '<div class="mailpoet_recaptcha" data-sitekey="' . $site_key . '">
|
||||||
<div class="mailpoet_recaptcha_container"></div>
|
<div class="mailpoet_recaptcha_container"></div>
|
||||||
<noscript>
|
<noscript>
|
||||||
|
@ -8,6 +8,7 @@ use MailPoet\Config\Renderer as ConfigRenderer;
|
|||||||
use MailPoet\Form\Renderer as FormRenderer;
|
use MailPoet\Form\Renderer as FormRenderer;
|
||||||
use MailPoet\Models\Form;
|
use MailPoet\Models\Form;
|
||||||
use MailPoet\Settings\SettingsController;
|
use MailPoet\Settings\SettingsController;
|
||||||
|
use MailPoet\Subscription\Captcha;
|
||||||
use MailPoet\Util\Security;
|
use MailPoet\Util\Security;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
|
|
||||||
@ -117,8 +118,8 @@ class Widget extends \WP_Widget {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
$captcha = $this->settings->get('re_captcha');
|
$captcha = $this->settings->get('captcha');
|
||||||
if (!empty($captcha['enabled'])) {
|
if (!empty($captcha['type']) && $captcha['type'] === Captcha::TYPE_RECAPTCHA) {
|
||||||
WPFunctions::get()->wpEnqueueScript(
|
WPFunctions::get()->wpEnqueueScript(
|
||||||
'mailpoet_recaptcha',
|
'mailpoet_recaptcha',
|
||||||
self::RECAPTCHA_API_URL,
|
self::RECAPTCHA_API_URL,
|
||||||
|
@ -9,10 +9,14 @@ if (!defined('ABSPATH')) exit;
|
|||||||
|
|
||||||
class Subscription {
|
class Subscription {
|
||||||
const ENDPOINT = 'subscription';
|
const ENDPOINT = 'subscription';
|
||||||
|
const ACTION_CAPTCHA = 'captcha';
|
||||||
|
const ACTION_CAPTCHA_IMAGE = 'captchaImage';
|
||||||
const ACTION_CONFIRM = 'confirm';
|
const ACTION_CONFIRM = 'confirm';
|
||||||
const ACTION_MANAGE = 'manage';
|
const ACTION_MANAGE = 'manage';
|
||||||
const ACTION_UNSUBSCRIBE = 'unsubscribe';
|
const ACTION_UNSUBSCRIBE = 'unsubscribe';
|
||||||
public $allowed_actions = [
|
public $allowed_actions = [
|
||||||
|
self::ACTION_CAPTCHA,
|
||||||
|
self::ACTION_CAPTCHA_IMAGE,
|
||||||
self::ACTION_CONFIRM,
|
self::ACTION_CONFIRM,
|
||||||
self::ACTION_MANAGE,
|
self::ACTION_MANAGE,
|
||||||
self::ACTION_UNSUBSCRIBE,
|
self::ACTION_UNSUBSCRIBE,
|
||||||
@ -28,6 +32,17 @@ class Subscription {
|
|||||||
$this->subscription_pages = $subscription_pages;
|
$this->subscription_pages = $subscription_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function captcha($data) {
|
||||||
|
$subscription = $this->initSubscriptionPage(UserSubscription\Pages::ACTION_CAPTCHA, $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function captchaImage($data) {
|
||||||
|
$captcha = new UserSubscription\Captcha;
|
||||||
|
$width = !empty($data['width']) ? (int)$data['width'] : null;
|
||||||
|
$height = !empty($data['height']) ? (int)$data['height'] : null;
|
||||||
|
return $captcha->renderImage($width, $height);
|
||||||
|
}
|
||||||
|
|
||||||
function confirm($data) {
|
function confirm($data) {
|
||||||
$subscription = $this->initSubscriptionPage(UserSubscription\Pages::ACTION_CONFIRM, $data);
|
$subscription = $this->initSubscriptionPage(UserSubscription\Pages::ACTION_CONFIRM, $data);
|
||||||
$subscription->confirm();
|
$subscription->confirm();
|
||||||
|
@ -2,12 +2,42 @@
|
|||||||
|
|
||||||
namespace MailPoet\Subscription;
|
namespace MailPoet\Subscription;
|
||||||
|
|
||||||
|
use MailPoetVendor\Gregwar\Captcha\CaptchaBuilder;
|
||||||
|
|
||||||
class Captcha {
|
class Captcha {
|
||||||
const TYPE_BUILTIN = 'built-in';
|
const TYPE_BUILTIN = 'built-in';
|
||||||
const TYPE_RECAPTCHA = 'recaptcha';
|
const TYPE_RECAPTCHA = 'recaptcha';
|
||||||
const TYPE_DISABLED = null;
|
const TYPE_DISABLED = null;
|
||||||
|
|
||||||
|
const SESSION_KEY = 'mailpoet_captcha';
|
||||||
|
const SESSION_FORM_KEY = 'mailpoet_captcha_form';
|
||||||
|
|
||||||
function isSupported() {
|
function isSupported() {
|
||||||
return extension_loaded('gd') && function_exists('imagettftext');
|
return extension_loaded('gd') && function_exists('imagettftext');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderImage($width = null, $height = null) {
|
||||||
|
if (!$this->isSupported()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$font_numbers = array_merge(range(0, 3), [5]); // skip font #4
|
||||||
|
$font_number = $font_numbers[mt_rand(0, count($font_numbers) - 1)];
|
||||||
|
|
||||||
|
$reflector = new \ReflectionClass(CaptchaBuilder::class);
|
||||||
|
$captcha_directory = dirname($reflector->getFileName());
|
||||||
|
$font = $captcha_directory . '/Font/captcha' . $font_number . '.ttf';
|
||||||
|
|
||||||
|
$builder = CaptchaBuilder::create()
|
||||||
|
->setBackgroundColor(255, 255, 255)
|
||||||
|
->setTextColor(1, 1, 1)
|
||||||
|
->setMaxBehindLines(0)
|
||||||
|
->build($width ?: 220, $height ?: 60, $font);
|
||||||
|
|
||||||
|
$_SESSION[self::SESSION_KEY] = $builder->getPhrase();
|
||||||
|
|
||||||
|
header('Content-Type: image/jpeg');
|
||||||
|
$builder->output();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ use MailPoet\WP\Functions as WPFunctions;
|
|||||||
|
|
||||||
class Pages {
|
class Pages {
|
||||||
const DEMO_EMAIL = 'demo@mailpoet.com';
|
const DEMO_EMAIL = 'demo@mailpoet.com';
|
||||||
|
const ACTION_CAPTCHA = 'captcha';
|
||||||
const ACTION_CONFIRM = 'confirm';
|
const ACTION_CONFIRM = 'confirm';
|
||||||
const ACTION_MANAGE = 'manage';
|
const ACTION_MANAGE = 'manage';
|
||||||
const ACTION_UNSUBSCRIBE = 'unsubscribe';
|
const ACTION_UNSUBSCRIBE = 'unsubscribe';
|
||||||
@ -159,6 +160,9 @@ class Pages {
|
|||||||
} else {
|
} else {
|
||||||
// when it's our own page, generate page title based on requested action
|
// when it's our own page, generate page title based on requested action
|
||||||
switch ($this->action) {
|
switch ($this->action) {
|
||||||
|
case self::ACTION_CAPTCHA:
|
||||||
|
return $this->getCaptchaTitle();
|
||||||
|
|
||||||
case self::ACTION_CONFIRM:
|
case self::ACTION_CONFIRM:
|
||||||
return $this->getConfirmTitle();
|
return $this->getConfirmTitle();
|
||||||
|
|
||||||
@ -183,6 +187,9 @@ class Pages {
|
|||||||
$content = '';
|
$content = '';
|
||||||
|
|
||||||
switch ($this->action) {
|
switch ($this->action) {
|
||||||
|
case self::ACTION_CAPTCHA:
|
||||||
|
$content = $this->getCaptchaContent();
|
||||||
|
break;
|
||||||
case self::ACTION_CONFIRM:
|
case self::ACTION_CONFIRM:
|
||||||
$content = $this->getConfirmContent();
|
$content = $this->getConfirmContent();
|
||||||
break;
|
break;
|
||||||
@ -217,6 +224,10 @@ class Pages {
|
|||||||
return $meta;
|
return $meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getCaptchaTitle() {
|
||||||
|
return WPFunctions::get()->__("Confirm you’re not a robot", 'mailpoet');
|
||||||
|
}
|
||||||
|
|
||||||
private function getConfirmTitle() {
|
private function getConfirmTitle() {
|
||||||
if ($this->isPreview()) {
|
if ($this->isPreview()) {
|
||||||
$title = sprintf(
|
$title = sprintf(
|
||||||
@ -252,6 +263,65 @@ class Pages {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getCaptchaContent() {
|
||||||
|
$fields = [
|
||||||
|
[
|
||||||
|
'id' => 'captcha',
|
||||||
|
'type' => 'text',
|
||||||
|
'params' => [
|
||||||
|
'label' => WPFunctions::get()->__('Type in the input the characters you see in the picture above:', 'mailpoet'),
|
||||||
|
'value' => '',
|
||||||
|
'obfuscate' => false,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$form = array_merge(
|
||||||
|
$fields,
|
||||||
|
[
|
||||||
|
[
|
||||||
|
'id' => 'submit',
|
||||||
|
'type' => 'submit',
|
||||||
|
'params' => [
|
||||||
|
'label' => WPFunctions::get()->__('Subscribe', 'mailpoet'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$form_id = isset($_SESSION[Captcha::SESSION_FORM_KEY]['form_id']) ? (int)$_SESSION[Captcha::SESSION_FORM_KEY]['form_id'] : 0;
|
||||||
|
|
||||||
|
$form_html = '<form method="POST" ' .
|
||||||
|
'action="' . admin_url('admin-post.php?action=mailpoet_subscription_form') . '" ' .
|
||||||
|
'class="mailpoet_form mailpoet_captcha_form" ' .
|
||||||
|
'novalidate>';
|
||||||
|
$form_html .= '<input type="hidden" name="data[form_id]" value="' . $form_id . '" />';
|
||||||
|
$form_html .= '<input type="hidden" name="api_version" value="v1" />';
|
||||||
|
$form_html .= '<input type="hidden" name="endpoint" value="subscribers" />';
|
||||||
|
$form_html .= '<input type="hidden" name="mailpoet_method" value="subscribe" />';
|
||||||
|
$form_html .= '<input type="hidden" name="mailpoet_redirect" ' .
|
||||||
|
'value="' . htmlspecialchars($this->url_helper->getCurrentUrl(), ENT_QUOTES) . '" />';
|
||||||
|
|
||||||
|
$width = 220;
|
||||||
|
$height = 60;
|
||||||
|
$captcha_url = Url::getCaptchaImageUrl($width, $height);
|
||||||
|
|
||||||
|
$form_html .= '<div class="mailpoet_form_hide_on_success">';
|
||||||
|
$form_html .= '<p class="mailpoet_paragraph">';
|
||||||
|
$form_html .= '<img class="mailpoet_captcha mailpoet_captcha_update" src="' . $captcha_url . '" width="' . $width . '" height="' . $height . '" title="' . WPFunctions::get()->__('Click to refresh the captcha', 'mailpoet') . '" />';
|
||||||
|
$form_html .= '</p>';
|
||||||
|
|
||||||
|
// subscription form
|
||||||
|
$form_html .= FormRenderer::renderBlocks($form, $honeypot = false);
|
||||||
|
$form_html .= '</div>';
|
||||||
|
$form_html .= '<div class="mailpoet_message">';
|
||||||
|
$form_html .= '<p class="mailpoet_validate_success" style="display:none;">Check your inbox or spam folder to confirm your subscription.</p>';
|
||||||
|
$form_html .= '<p class="mailpoet_validate_error" style="display:none;"></p>';
|
||||||
|
$form_html .= '</div>';
|
||||||
|
$form_html .= '</form>';
|
||||||
|
return $form_html;
|
||||||
|
}
|
||||||
|
|
||||||
private function getConfirmContent() {
|
private function getConfirmContent() {
|
||||||
if ($this->isPreview() || $this->subscriber !== false) {
|
if ($this->isPreview() || $this->subscriber !== false) {
|
||||||
return $this->wp->__("Yup, we've added you to our email list. You'll hear from us shortly.", 'mailpoet');
|
return $this->wp->__("Yup, we've added you to our email list. You'll hear from us shortly.", 'mailpoet');
|
||||||
|
@ -8,6 +8,16 @@ use MailPoet\Settings\SettingsController;
|
|||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
|
|
||||||
class Url {
|
class Url {
|
||||||
|
static function getCaptchaUrl(Subscriber $subscriber = null) {
|
||||||
|
$post = WPFunctions::get()->getPost(self::getSetting('subscription.pages.captcha'));
|
||||||
|
return self::getSubscriptionUrl($post, 'captcha', $subscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function getCaptchaImageUrl($width, $height) {
|
||||||
|
$post = WPFunctions::get()->getPost(self::getSetting('subscription.pages.captcha'));
|
||||||
|
return self::getSubscriptionUrl($post, 'captchaImage', null, ['width' => $width, 'height' => $height]);
|
||||||
|
}
|
||||||
|
|
||||||
static function getConfirmationUrl(Subscriber $subscriber = null) {
|
static function getConfirmationUrl(Subscriber $subscriber = null) {
|
||||||
$post = WPFunctions::get()->getPost(self::getSetting('subscription.pages.confirmation'));
|
$post = WPFunctions::get()->getPost(self::getSetting('subscription.pages.confirmation'));
|
||||||
return self::getSubscriptionUrl($post, 'confirm', $subscriber);
|
return self::getSubscriptionUrl($post, 'confirm', $subscriber);
|
||||||
@ -24,7 +34,10 @@ class Url {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static function getSubscriptionUrl(
|
static function getSubscriptionUrl(
|
||||||
$post = null, $action = null, Subscriber $subscriber = null
|
$post = null,
|
||||||
|
$action = null,
|
||||||
|
Subscriber $subscriber = null,
|
||||||
|
$data = null
|
||||||
) {
|
) {
|
||||||
if ($post === null || $action === null) return;
|
if ($post === null || $action === null) return;
|
||||||
|
|
||||||
@ -35,7 +48,7 @@ class Url {
|
|||||||
'token' => Subscriber::generateToken($subscriber->email),
|
'token' => Subscriber::generateToken($subscriber->email),
|
||||||
'email' => $subscriber->email,
|
'email' => $subscriber->email,
|
||||||
];
|
];
|
||||||
} else {
|
} elseif (is_null($data)) {
|
||||||
$data = [
|
$data = [
|
||||||
'preview' => 1,
|
'preview' => 1,
|
||||||
];
|
];
|
||||||
|
Reference in New Issue
Block a user