Form Subscription
- improved MailPoet ajax to fix token issue - added js validation and ajax submit in public.js - add util security to generate tokens - updated router to use new util security - added jquery-validation module - update public config in webpack config - added error messages in form
This commit is contained in:
@@ -28,6 +28,11 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
|||||||
if(this.options.url === null) {
|
if(this.options.url === null) {
|
||||||
this.options.url = ajaxurl;
|
this.options.url = ajaxurl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set default token
|
||||||
|
if(this.options.token === null) {
|
||||||
|
this.options.token = mailpoet_token;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
request: function(method, options) {
|
request: function(method, options) {
|
||||||
// set options
|
// set options
|
||||||
@@ -36,7 +41,7 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
|||||||
// set request params
|
// set request params
|
||||||
var params = {
|
var params = {
|
||||||
action: 'mailpoet',
|
action: 'mailpoet',
|
||||||
token: mailpoet_token,
|
token: this.options.token,
|
||||||
endpoint: this.options.endpoint,
|
endpoint: this.options.endpoint,
|
||||||
method: this.options.action,
|
method: this.options.action,
|
||||||
data: this.options.data
|
data: this.options.data
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
define('public', ['jquery', 'jquery-validation'],
|
define('public', ['mailpoet', 'jquery', 'jquery-validation'],
|
||||||
function($) {
|
function(MailPoet, $) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
function isSameDomain(url) {
|
function isSameDomain(url) {
|
||||||
var link = document.createElement('a');
|
var link = document.createElement('a');
|
||||||
@@ -7,14 +8,77 @@ define('public', ['jquery', 'jquery-validation'],
|
|||||||
return (window.location.hostname === link.hostname);
|
return (window.location.hostname === link.hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatData(raw) {
|
||||||
|
var data = {};
|
||||||
|
|
||||||
|
$.each(raw, function(index, value) {
|
||||||
|
if(value.name.endsWith('[]')) {
|
||||||
|
var value_name = value.name.substr(0, value.name.length - 2);
|
||||||
|
// it's an array
|
||||||
|
if(data[value_name] === undefined) {
|
||||||
|
data[value_name] = [];
|
||||||
|
}
|
||||||
|
data[value_name].push(value.value);
|
||||||
|
} else {
|
||||||
|
data[value.name] = value.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
// setup form validation
|
// setup form validation
|
||||||
$('form.mailpoet_form').validate({
|
$('form.mailpoet_form').validate({
|
||||||
submitHandler: function(form) {
|
submitHandler: function(form) {
|
||||||
console.log(form);
|
var data = $(form).serializeArray() || {};
|
||||||
$(form).ajaxSubmit({
|
|
||||||
target: "#result"
|
// clear messages
|
||||||
});
|
$(form).find('.mailpoet_message').html('');
|
||||||
|
|
||||||
|
// check if we're on the same domain
|
||||||
|
if(isSameDomain(MailPoetForm.ajax_url) === false) {
|
||||||
|
// non ajax post request
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// ajax request
|
||||||
|
MailPoet.Ajax.post({
|
||||||
|
url: MailPoetForm.ajax_url,
|
||||||
|
token: MailPoetForm.token,
|
||||||
|
endpoint: 'subscribers',
|
||||||
|
action: 'save',
|
||||||
|
data: formatData(data),
|
||||||
|
onSuccess: function(response) {
|
||||||
|
if(response !== true) {
|
||||||
|
// errors
|
||||||
|
$.each(response, function(index, error) {
|
||||||
|
$(form)
|
||||||
|
.find('.mailpoet_message')
|
||||||
|
.append('<p class="mailpoet_validate_error">'+
|
||||||
|
error+
|
||||||
|
'</p>');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// successfully subscribed
|
||||||
|
if(response.page !== undefined) {
|
||||||
|
// go to page
|
||||||
|
window.location.href = response.page;
|
||||||
|
} else if(response.message !== undefined) {
|
||||||
|
// display success message
|
||||||
|
$(form)
|
||||||
|
.find('.mailpoet_message')
|
||||||
|
.html('<p class="mailpoet_validate_success">'+
|
||||||
|
response.message+
|
||||||
|
'</p>');
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset form
|
||||||
|
$(form).trigger('reset');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Config;
|
namespace MailPoet\Config;
|
||||||
|
use \MailPoet\Util\Security;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
@@ -18,19 +19,18 @@ class Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setupDependencies() {
|
function setupDependencies() {
|
||||||
wp_enqueue_script('mailpoet_vendor',
|
|
||||||
Env::$assets_url.'/js/vendor.js',
|
|
||||||
array(),
|
|
||||||
Env::$version,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
wp_enqueue_script('mailpoet_public',
|
wp_enqueue_script('mailpoet_public',
|
||||||
Env::$assets_url.'/js/public.js',
|
Env::$assets_url.'/js/public.js',
|
||||||
array(),
|
array(),
|
||||||
Env::$version,
|
Env::$version,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
wp_localize_script('mailpoet_public', 'MailPoetForm', array(
|
||||||
|
'ajax_url' => admin_url('admin-ajax.php'),
|
||||||
|
'is_rtl' => (function_exists('is_rtl') ? (bool)is_rtl() : false),
|
||||||
|
'token' => Security::generateToken()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupActions() {
|
function setupActions() {
|
||||||
|
@@ -85,10 +85,14 @@ class Widget extends \WP_Widget {
|
|||||||
'action="'.admin_url('admin-post.php?action=mailpoet_form_subscribe').'" '.
|
'action="'.admin_url('admin-post.php?action=mailpoet_form_subscribe').'" '.
|
||||||
'class="mailpoet_form mailpoet_form_'.$form_type.'" novalidate>';
|
'class="mailpoet_form mailpoet_form_'.$form_type.'" novalidate>';
|
||||||
|
|
||||||
|
$output .= '<div class="mailpoet_message"></div>';
|
||||||
|
|
||||||
$output .= ' <p>';
|
$output .= ' <p>';
|
||||||
$output .= ' <label>'.__('E-mail');
|
$output .= ' <label>'.__('E-mail');
|
||||||
$output .= ' <input type="email" name="email"';
|
$output .= ' <input type="email" name="email"';
|
||||||
$output .= ' data-validation-engine="validate[required,custom[email]]"';
|
$output .= ' data-validation-engine="validate[required,custom[email]]"';
|
||||||
|
$output .= ' data-msg="'.__('This field is required.').'"';
|
||||||
|
$output .= ' required';
|
||||||
$output .= ' />';
|
$output .= ' />';
|
||||||
$output .= ' </label>';
|
$output .= ' </label>';
|
||||||
$output .= ' </p>';
|
$output .= ' </p>';
|
||||||
|
@@ -10,16 +10,8 @@ class Subscriber extends Model {
|
|||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->addValidations('email', array(
|
$this->addValidations('email', array(
|
||||||
'required' => "email_is_blank",
|
'required' => __('You need to enter your email address.'),
|
||||||
'isEmail' => "email_is_invalid"
|
'isEmail' => __('Your email address is invalid.')
|
||||||
));
|
|
||||||
$this->addValidations('first_name', array(
|
|
||||||
'required' => "first_name_is_blank",
|
|
||||||
"isString" => "name_is_not_string"
|
|
||||||
));
|
|
||||||
$this->addValidations('last_name', array(
|
|
||||||
'required' => "last_name_is_blank",
|
|
||||||
"isString" => "name_is_not_string"
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Router;
|
namespace MailPoet\Router;
|
||||||
|
use \MailPoet\Util\Security;
|
||||||
|
|
||||||
if(!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
@@ -29,9 +30,8 @@ class Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setToken() {
|
function setToken() {
|
||||||
$token = wp_create_nonce('mailpoet_token');
|
|
||||||
$global = '<script type="text/javascript">';
|
$global = '<script type="text/javascript">';
|
||||||
$global .= 'var mailpoet_token = "' . $token . '";';
|
$global .= 'var mailpoet_token = "'.Security::generateToken().'";';
|
||||||
$global .= "</script>/n";
|
$global .= "</script>/n";
|
||||||
echo $global;
|
echo $global;
|
||||||
}
|
}
|
||||||
|
8
lib/Util/Security.php
Normal file
8
lib/Util/Security.php
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Util;
|
||||||
|
|
||||||
|
class Security {
|
||||||
|
static function generateToken() {
|
||||||
|
return wp_create_nonce('mailpoet_token');
|
||||||
|
}
|
||||||
|
}
|
@@ -17,6 +17,7 @@
|
|||||||
"d3": "~3.5.5",
|
"d3": "~3.5.5",
|
||||||
"handlebars": "3.0.3",
|
"handlebars": "3.0.3",
|
||||||
"html2canvas": "latest",
|
"html2canvas": "latest",
|
||||||
|
"jquery-validation": "^1.14.0",
|
||||||
"moment": "^2.10.3",
|
"moment": "^2.10.3",
|
||||||
"napa": "^1.2.0",
|
"napa": "^1.2.0",
|
||||||
"papaparse": "4.1.1",
|
"papaparse": "4.1.1",
|
||||||
|
@@ -48,7 +48,7 @@ config.push(_.extend({}, baseConfig, {
|
|||||||
config.push(_.extend({}, baseConfig, {
|
config.push(_.extend({}, baseConfig, {
|
||||||
name: 'public',
|
name: 'public',
|
||||||
entry: {
|
entry: {
|
||||||
public: 'public.js'
|
public: ['mailpoet', 'ajax', 'public.js']
|
||||||
},
|
},
|
||||||
externals: {
|
externals: {
|
||||||
'jquery': 'jQuery'
|
'jquery': 'jQuery'
|
||||||
|
Reference in New Issue
Block a user