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:
Jonathan Labreuille
2015-08-20 21:02:04 +02:00
parent 1c77536cf5
commit 1ff7e3f4be
9 changed files with 101 additions and 27 deletions

View File

@@ -28,6 +28,11 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
if(this.options.url === null) {
this.options.url = ajaxurl;
}
// set default token
if(this.options.token === null) {
this.options.token = mailpoet_token;
}
},
request: function(method, options) {
// set options
@@ -36,7 +41,7 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
// set request params
var params = {
action: 'mailpoet',
token: mailpoet_token,
token: this.options.token,
endpoint: this.options.endpoint,
method: this.options.action,
data: this.options.data

View File

@@ -1,5 +1,6 @@
define('public', ['jquery', 'jquery-validation'],
function($) {
define('public', ['mailpoet', 'jquery', 'jquery-validation'],
function(MailPoet, $) {
'use strict';
function isSameDomain(url) {
var link = document.createElement('a');
@@ -7,14 +8,77 @@ define('public', ['jquery', 'jquery-validation'],
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() {
// setup form validation
$('form.mailpoet_form').validate({
submitHandler: function(form) {
console.log(form);
$(form).ajaxSubmit({
target: "#result"
var data = $(form).serializeArray() || {};
// 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;
}
});
});

View File

@@ -1,5 +1,6 @@
<?php
namespace MailPoet\Config;
use \MailPoet\Util\Security;
if(!defined('ABSPATH')) exit;
@@ -18,19 +19,18 @@ class Widget {
}
function setupDependencies() {
wp_enqueue_script('mailpoet_vendor',
Env::$assets_url.'/js/vendor.js',
array(),
Env::$version,
true
);
wp_enqueue_script('mailpoet_public',
Env::$assets_url.'/js/public.js',
array(),
Env::$version,
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() {

View File

@@ -85,10 +85,14 @@ class Widget extends \WP_Widget {
'action="'.admin_url('admin-post.php?action=mailpoet_form_subscribe').'" '.
'class="mailpoet_form mailpoet_form_'.$form_type.'" novalidate>';
$output .= '<div class="mailpoet_message"></div>';
$output .= ' <p>';
$output .= ' <label>'.__('E-mail');
$output .= ' <input type="email" name="email"';
$output .= ' data-validation-engine="validate[required,custom[email]]"';
$output .= ' data-msg="'.__('This field is required.').'"';
$output .= ' required';
$output .= ' />';
$output .= ' </label>';
$output .= ' </p>';

View File

@@ -10,16 +10,8 @@ class Subscriber extends Model {
parent::__construct();
$this->addValidations('email', array(
'required' => "email_is_blank",
'isEmail' => "email_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"
'required' => __('You need to enter your email address.'),
'isEmail' => __('Your email address is invalid.')
));
}
}

View File

@@ -1,5 +1,6 @@
<?php
namespace MailPoet\Router;
use \MailPoet\Util\Security;
if(!defined('ABSPATH')) exit;
@@ -29,9 +30,8 @@ class Router {
}
function setToken() {
$token = wp_create_nonce('mailpoet_token');
$global = '<script type="text/javascript">';
$global .= 'var mailpoet_token = "' . $token . '";';
$global .= 'var mailpoet_token = "'.Security::generateToken().'";';
$global .= "</script>/n";
echo $global;
}

8
lib/Util/Security.php Normal file
View File

@@ -0,0 +1,8 @@
<?php
namespace MailPoet\Util;
class Security {
static function generateToken() {
return wp_create_nonce('mailpoet_token');
}
}

View File

@@ -17,6 +17,7 @@
"d3": "~3.5.5",
"handlebars": "3.0.3",
"html2canvas": "latest",
"jquery-validation": "^1.14.0",
"moment": "^2.10.3",
"napa": "^1.2.0",
"papaparse": "4.1.1",

View File

@@ -48,7 +48,7 @@ config.push(_.extend({}, baseConfig, {
config.push(_.extend({}, baseConfig, {
name: 'public',
entry: {
public: 'public.js'
public: ['mailpoet', 'ajax', 'public.js']
},
externals: {
'jquery': 'jQuery'