Add captcha page [MAILPOET-2015]
This commit is contained in:
@ -44,6 +44,15 @@
|
||||
margin: 0 7px;
|
||||
}
|
||||
|
||||
.mailpoet_captcha_form {
|
||||
.mailpoet_validate_success { color: #468847; }
|
||||
.mailpoet_validate_error { color: #b94a48; }
|
||||
}
|
||||
|
||||
.mailpoet_captcha_update {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@keyframes mailpoet-bouncedelay {
|
||||
0%,
|
||||
80%,
|
||||
|
@ -175,6 +175,7 @@ class Populator {
|
||||
'unsubscribe' => $mailpoet_page_id,
|
||||
'manage' => $mailpoet_page_id,
|
||||
'confirmation' => $mailpoet_page_id,
|
||||
'captcha' => $mailpoet_page_id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,8 @@ abstract class Base {
|
||||
protected static function getFieldName($block = []) {
|
||||
if ((int)$block['id'] > 0) {
|
||||
return 'cf_' . $block['id'];
|
||||
} elseif (isset($block['params']['obfuscate']) && !$block['params']['obfuscate']) {
|
||||
return $block['id'];
|
||||
} else {
|
||||
$obfuscator = new FieldNameObfuscator();
|
||||
return $obfuscator->obfuscate($block['id']);//obfuscate field name for spambots
|
||||
|
@ -2,6 +2,7 @@
|
||||
namespace MailPoet\Form;
|
||||
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\Subscription\Captcha;
|
||||
|
||||
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>' :
|
||||
'';
|
||||
foreach ($blocks as $key => $block) {
|
||||
if ($block['type'] == 'submit' && $settings->get('re_captcha.enabled')) {
|
||||
$site_key = $settings->get('re_captcha.site_token');
|
||||
if ($block['type'] == 'submit' && $settings->get('captcha.type') === Captcha::TYPE_RECAPTCHA) {
|
||||
$site_key = $settings->get('captcha.recaptcha_site_token');
|
||||
$html .= '<div class="mailpoet_recaptcha" data-sitekey="' . $site_key . '">
|
||||
<div class="mailpoet_recaptcha_container"></div>
|
||||
<noscript>
|
||||
|
@ -8,6 +8,7 @@ use MailPoet\Config\Renderer as ConfigRenderer;
|
||||
use MailPoet\Form\Renderer as FormRenderer;
|
||||
use MailPoet\Models\Form;
|
||||
use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\Subscription\Captcha;
|
||||
use MailPoet\Util\Security;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
|
||||
@ -117,8 +118,8 @@ class Widget extends \WP_Widget {
|
||||
true
|
||||
);
|
||||
|
||||
$captcha = $this->settings->get('re_captcha');
|
||||
if (!empty($captcha['enabled'])) {
|
||||
$captcha = $this->settings->get('captcha');
|
||||
if (!empty($captcha['type']) && $captcha['type'] === Captcha::TYPE_RECAPTCHA) {
|
||||
WPFunctions::get()->wpEnqueueScript(
|
||||
'mailpoet_recaptcha',
|
||||
self::RECAPTCHA_API_URL,
|
||||
|
@ -9,10 +9,14 @@ if (!defined('ABSPATH')) exit;
|
||||
|
||||
class Subscription {
|
||||
const ENDPOINT = 'subscription';
|
||||
const ACTION_CAPTCHA = 'captcha';
|
||||
const ACTION_CAPTCHA_IMAGE = 'captchaImage';
|
||||
const ACTION_CONFIRM = 'confirm';
|
||||
const ACTION_MANAGE = 'manage';
|
||||
const ACTION_UNSUBSCRIBE = 'unsubscribe';
|
||||
public $allowed_actions = [
|
||||
self::ACTION_CAPTCHA,
|
||||
self::ACTION_CAPTCHA_IMAGE,
|
||||
self::ACTION_CONFIRM,
|
||||
self::ACTION_MANAGE,
|
||||
self::ACTION_UNSUBSCRIBE,
|
||||
@ -28,6 +32,17 @@ class Subscription {
|
||||
$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) {
|
||||
$subscription = $this->initSubscriptionPage(UserSubscription\Pages::ACTION_CONFIRM, $data);
|
||||
$subscription->confirm();
|
||||
|
@ -2,12 +2,42 @@
|
||||
|
||||
namespace MailPoet\Subscription;
|
||||
|
||||
use MailPoetVendor\Gregwar\Captcha\CaptchaBuilder;
|
||||
|
||||
class Captcha {
|
||||
const TYPE_BUILTIN = 'built-in';
|
||||
const TYPE_RECAPTCHA = 'recaptcha';
|
||||
const TYPE_DISABLED = null;
|
||||
|
||||
const SESSION_KEY = 'mailpoet_captcha';
|
||||
const SESSION_FORM_KEY = 'mailpoet_captcha_form';
|
||||
|
||||
function isSupported() {
|
||||
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 {
|
||||
const DEMO_EMAIL = 'demo@mailpoet.com';
|
||||
const ACTION_CAPTCHA = 'captcha';
|
||||
const ACTION_CONFIRM = 'confirm';
|
||||
const ACTION_MANAGE = 'manage';
|
||||
const ACTION_UNSUBSCRIBE = 'unsubscribe';
|
||||
@ -159,6 +160,9 @@ class Pages {
|
||||
} else {
|
||||
// when it's our own page, generate page title based on requested action
|
||||
switch ($this->action) {
|
||||
case self::ACTION_CAPTCHA:
|
||||
return $this->getCaptchaTitle();
|
||||
|
||||
case self::ACTION_CONFIRM:
|
||||
return $this->getConfirmTitle();
|
||||
|
||||
@ -183,6 +187,9 @@ class Pages {
|
||||
$content = '';
|
||||
|
||||
switch ($this->action) {
|
||||
case self::ACTION_CAPTCHA:
|
||||
$content = $this->getCaptchaContent();
|
||||
break;
|
||||
case self::ACTION_CONFIRM:
|
||||
$content = $this->getConfirmContent();
|
||||
break;
|
||||
@ -217,6 +224,10 @@ class Pages {
|
||||
return $meta;
|
||||
}
|
||||
|
||||
private function getCaptchaTitle() {
|
||||
return WPFunctions::get()->__("Confirm you’re not a robot", 'mailpoet');
|
||||
}
|
||||
|
||||
private function getConfirmTitle() {
|
||||
if ($this->isPreview()) {
|
||||
$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() {
|
||||
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');
|
||||
|
@ -8,6 +8,16 @@ use MailPoet\Settings\SettingsController;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
|
||||
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) {
|
||||
$post = WPFunctions::get()->getPost(self::getSetting('subscription.pages.confirmation'));
|
||||
return self::getSubscriptionUrl($post, 'confirm', $subscriber);
|
||||
@ -24,7 +34,10 @@ class Url {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -35,7 +48,7 @@ class Url {
|
||||
'token' => Subscriber::generateToken($subscriber->email),
|
||||
'email' => $subscriber->email,
|
||||
];
|
||||
} else {
|
||||
} elseif (is_null($data)) {
|
||||
$data = [
|
||||
'preview' => 1,
|
||||
];
|
||||
|
Reference in New Issue
Block a user