Fix fubscription form failing when some fields are absent or don't exist [MAILPOET-764]
This commit is contained in:
@ -65,6 +65,12 @@ class Subscribers extends APIEndpoint {
|
|||||||
$form = Form::findOne($form_id);
|
$form = Form::findOne($form_id);
|
||||||
unset($data['form_id']);
|
unset($data['form_id']);
|
||||||
|
|
||||||
|
if(!$form) {
|
||||||
|
return $this->badRequest(array(
|
||||||
|
APIError::BAD_REQUEST => __('Please specify a valid form ID.', 'mailpoet')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
$segment_ids = (!empty($data['segments'])
|
$segment_ids = (!empty($data['segments'])
|
||||||
? (array)$data['segments']
|
? (array)$data['segments']
|
||||||
: array()
|
: array()
|
||||||
@ -77,6 +83,10 @@ class Subscribers extends APIEndpoint {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only accept fields defined in the form
|
||||||
|
$form_fields = $form->getFieldList();
|
||||||
|
$data = array_intersect_key($data, array_flip($form_fields));
|
||||||
|
|
||||||
$subscriber = Subscriber::subscribe($data, $segment_ids);
|
$subscriber = Subscriber::subscribe($data, $segment_ids);
|
||||||
$errors = $subscriber->getErrors();
|
$errors = $subscriber->getErrors();
|
||||||
|
|
||||||
|
@ -39,6 +39,32 @@ class Form extends Model {
|
|||||||
return parent::save();
|
return parent::save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getFieldList() {
|
||||||
|
$form = $this->asArray();
|
||||||
|
if(empty($form['body'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$skipped_types = array('html', 'divider', 'submit');
|
||||||
|
$fields = array();
|
||||||
|
|
||||||
|
foreach((array)$form['body'] as $field) {
|
||||||
|
if(empty($field['id'])
|
||||||
|
|| empty($field['type'])
|
||||||
|
|| in_array($field['type'], $skipped_types)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if($field['id'] > 0) {
|
||||||
|
$fields[] = 'cf_' . $field['id'];
|
||||||
|
} else {
|
||||||
|
$fields[] = $field['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fields ?: false;
|
||||||
|
}
|
||||||
|
|
||||||
static function search($orm, $search = '') {
|
static function search($orm, $search = '') {
|
||||||
return $orm->whereLike('name', '%'.$search.'%');
|
return $orm->whereLike('name', '%'.$search.'%');
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Codeception\Util\Fixtures;
|
||||||
use \MailPoet\API\Endpoints\Subscribers;
|
use \MailPoet\API\Endpoints\Subscribers;
|
||||||
use \MailPoet\API\Response as APIResponse;
|
use \MailPoet\API\Response as APIResponse;
|
||||||
|
use \MailPoet\Models\Form;
|
||||||
use \MailPoet\Models\Subscriber;
|
use \MailPoet\Models\Subscriber;
|
||||||
use \MailPoet\Models\Segment;
|
use \MailPoet\Models\Segment;
|
||||||
use \MailPoet\Models\Setting;
|
use \MailPoet\Models\Setting;
|
||||||
@ -28,6 +30,11 @@ class SubscribersTest extends MailPoetTest {
|
|||||||
)
|
)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$this->form = Form::createOrUpdate(array(
|
||||||
|
'name' => 'My Form',
|
||||||
|
'body' => Fixtures::get('form_body_template')
|
||||||
|
));
|
||||||
|
|
||||||
// setup mailer
|
// setup mailer
|
||||||
Setting::setValue('sender', array(
|
Setting::setValue('sender', array(
|
||||||
'address' => 'sender@mailpoet.com',
|
'address' => 'sender@mailpoet.com',
|
||||||
@ -375,10 +382,22 @@ class SubscribersTest extends MailPoetTest {
|
|||||||
expect($response->errors[0]['message'])->contains('has no method');
|
expect($response->errors[0]['message'])->contains('has no method');
|
||||||
}
|
}
|
||||||
|
|
||||||
function testItCannotSubscribeWithoutSegments() {
|
function testItCannotSubscribeWithoutFormID() {
|
||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com'
|
'email' => 'toto@mailpoet.com'
|
||||||
|
// no form ID specified
|
||||||
|
));
|
||||||
|
|
||||||
|
expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST);
|
||||||
|
expect($response->errors[0]['message'])->equals('Please specify a valid form ID.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testItCannotSubscribeWithoutSegments() {
|
||||||
|
$router = new Subscribers();
|
||||||
|
$response = $router->subscribe(array(
|
||||||
|
'email' => 'toto@mailpoet.com',
|
||||||
|
'form_id' => $this->form->id
|
||||||
// no segments specified
|
// no segments specified
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -390,23 +409,46 @@ class SubscribersTest extends MailPoetTest {
|
|||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com',
|
'email' => 'toto@mailpoet.com',
|
||||||
|
'form_id' => $this->form->id,
|
||||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||||
));
|
));
|
||||||
expect($response->status)->equals(APIResponse::STATUS_OK);
|
expect($response->status)->equals(APIResponse::STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testItCanFilterOutNonFormFieldsWhenSubscribing() {
|
||||||
|
$router = new Subscribers();
|
||||||
|
$response = $router->subscribe(array(
|
||||||
|
'email' => 'toto@mailpoet.com',
|
||||||
|
'form_id' => $this->form->id,
|
||||||
|
'segments' => array($this->segment_1->id, $this->segment_2->id),
|
||||||
|
// exists in table and in the form
|
||||||
|
'first_name' => 'aaa',
|
||||||
|
// exists in table, but not in the form
|
||||||
|
'last_name' => 'bbb',
|
||||||
|
// doesn't exist
|
||||||
|
'bogus' => 'hahaha'
|
||||||
|
));
|
||||||
|
expect($response->status)->equals(APIResponse::STATUS_OK);
|
||||||
|
$subscriber = Subscriber::findOne($response->data['id']);
|
||||||
|
expect($subscriber->first_name)->equals('aaa');
|
||||||
|
expect($subscriber->last_name)->isEmpty();
|
||||||
|
expect(isset($subscriber->bogus))->false();
|
||||||
|
}
|
||||||
|
|
||||||
function testItCannotMassSubscribe() {
|
function testItCannotMassSubscribe() {
|
||||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||||
|
|
||||||
$router = new Subscribers();
|
$router = new Subscribers();
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'toto@mailpoet.com',
|
'email' => 'toto@mailpoet.com',
|
||||||
|
'form_id' => $this->form->id,
|
||||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||||
));
|
));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$response = $router->subscribe(array(
|
$response = $router->subscribe(array(
|
||||||
'email' => 'tata@mailpoet.com',
|
'email' => 'tata@mailpoet.com',
|
||||||
|
'form_id' => $this->form->id,
|
||||||
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
'segments' => array($this->segment_1->id, $this->segment_2->id)
|
||||||
));
|
));
|
||||||
$this->fail('It should not be possible to subscribe a second time so soon');
|
$this->fail('It should not be possible to subscribe a second time so soon');
|
||||||
|
@ -92,6 +92,26 @@ class FormTest extends MailPoetTest {
|
|||||||
expect($form->name)->equals('Updated Form');
|
expect($form->name)->equals('Updated Form');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testItCanProvideAFieldList() {
|
||||||
|
$form = Form::createOrUpdate(array(
|
||||||
|
'name' => 'My Form',
|
||||||
|
'body' => array(
|
||||||
|
array(
|
||||||
|
'type' => 'text',
|
||||||
|
'id' => 'email',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'text',
|
||||||
|
'id' => 2,
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'submit',
|
||||||
|
'id' => 'submit',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
expect($form->getFieldList())->equals(array('email', 'cf_2'));
|
||||||
|
}
|
||||||
|
|
||||||
function _after() {
|
function _after() {
|
||||||
Form::deleteMany();
|
Form::deleteMany();
|
||||||
|
@ -44,3 +44,121 @@ Fixtures::add(
|
|||||||
'email' => 'john.doe@example.com'
|
'email' => 'john.doe@example.com'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Fixtures::add(
|
||||||
|
'form_body_template',
|
||||||
|
array(
|
||||||
|
array(
|
||||||
|
'type' => 'text',
|
||||||
|
'name' => 'First name',
|
||||||
|
'id' => 'first_name',
|
||||||
|
'unique' => '1',
|
||||||
|
'static' => '0',
|
||||||
|
'params' =>
|
||||||
|
array(
|
||||||
|
'label' => 'First name',
|
||||||
|
),
|
||||||
|
'position' => '1',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'text',
|
||||||
|
'name' => 'Nickname',
|
||||||
|
'id' => '4',
|
||||||
|
'unique' => '1',
|
||||||
|
'static' => '0',
|
||||||
|
'params' =>
|
||||||
|
array(
|
||||||
|
'label' => 'Nickname',
|
||||||
|
),
|
||||||
|
'position' => '2',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'text',
|
||||||
|
'name' => 'Age',
|
||||||
|
'id' => '2',
|
||||||
|
'unique' => '1',
|
||||||
|
'static' => '0',
|
||||||
|
'params' =>
|
||||||
|
array(
|
||||||
|
'required' => '',
|
||||||
|
'validate' => 'number',
|
||||||
|
'label' => 'Age',
|
||||||
|
),
|
||||||
|
'position' => '3',
|
||||||
|
),
|
||||||
|
array (
|
||||||
|
'type' => 'divider',
|
||||||
|
'name' => 'Divider',
|
||||||
|
'id' => 'divider',
|
||||||
|
'unique' => '0',
|
||||||
|
'static' => '0',
|
||||||
|
'params' => '',
|
||||||
|
'position' => '4',
|
||||||
|
),
|
||||||
|
array (
|
||||||
|
'type' => 'radio',
|
||||||
|
'name' => '3-way choice',
|
||||||
|
'id' => '3',
|
||||||
|
'unique' => '1',
|
||||||
|
'static' => '0',
|
||||||
|
'params' =>
|
||||||
|
array (
|
||||||
|
'values' =>
|
||||||
|
array (
|
||||||
|
0 =>
|
||||||
|
array (
|
||||||
|
'value' => '1',
|
||||||
|
),
|
||||||
|
1 =>
|
||||||
|
array (
|
||||||
|
'value' => '2',
|
||||||
|
),
|
||||||
|
2 =>
|
||||||
|
array (
|
||||||
|
'value' => '3',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'required' => '',
|
||||||
|
'label' => '3-way choice',
|
||||||
|
),
|
||||||
|
'position' => '5',
|
||||||
|
),
|
||||||
|
array (
|
||||||
|
'type' => 'html',
|
||||||
|
'name' => 'Random text or HTML',
|
||||||
|
'id' => 'html',
|
||||||
|
'unique' => '0',
|
||||||
|
'static' => '0',
|
||||||
|
'params' =>
|
||||||
|
array (
|
||||||
|
'text' => 'Subscribe to our newsletter and join [mailpoet_subscribers_count] other subscribers.',
|
||||||
|
),
|
||||||
|
'position' => '6',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'text',
|
||||||
|
'name' => 'Email',
|
||||||
|
'id' => 'email',
|
||||||
|
'unique' => '0',
|
||||||
|
'static' => '1',
|
||||||
|
'params' =>
|
||||||
|
array(
|
||||||
|
'label' => 'Email',
|
||||||
|
'required' => 'true',
|
||||||
|
),
|
||||||
|
'position' => '7',
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'type' => 'submit',
|
||||||
|
'name' => 'Submit',
|
||||||
|
'id' => 'submit',
|
||||||
|
'unique' => '0',
|
||||||
|
'static' => '1',
|
||||||
|
'params' =>
|
||||||
|
array(
|
||||||
|
'label' => 'Subscribe!',
|
||||||
|
),
|
||||||
|
'position' => '8',
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Reference in New Issue
Block a user