Conflicts between Segment and Subscriber status.
This commit is contained in:
@ -13,13 +13,13 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
|||||||
onError: function(xhr, textStatus, errorThrown) {}
|
onError: function(xhr, textStatus, errorThrown) {}
|
||||||
},
|
},
|
||||||
get: function(options) {
|
get: function(options) {
|
||||||
this.request('get', options);
|
return this.request('get', options);
|
||||||
},
|
},
|
||||||
post: function(options) {
|
post: function(options) {
|
||||||
this.request('post', options);
|
return this.request('post', options);
|
||||||
},
|
},
|
||||||
delete: function(options) {
|
delete: function(options) {
|
||||||
this.request('delete', options);
|
return this.request('delete', options);
|
||||||
},
|
},
|
||||||
init: function(options) {
|
init: function(options) {
|
||||||
// merge options
|
// merge options
|
||||||
@ -46,18 +46,18 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
|||||||
endpoint: this.options.endpoint,
|
endpoint: this.options.endpoint,
|
||||||
method: this.options.action,
|
method: this.options.action,
|
||||||
data: this.options.data || {}
|
data: this.options.data || {}
|
||||||
};
|
}, jqXHR;
|
||||||
|
|
||||||
// make ajax request depending on method
|
// make ajax request depending on method
|
||||||
if(method === 'get') {
|
if(method === 'get') {
|
||||||
jQuery.get(
|
jqXHR = jQuery.get(
|
||||||
this.options.url,
|
this.options.url,
|
||||||
params,
|
params,
|
||||||
this.options.onSuccess,
|
this.options.onSuccess,
|
||||||
'json'
|
'json'
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
jQuery.ajax({
|
jqXHR = jQuery.ajax({
|
||||||
url: this.options.url,
|
url: this.options.url,
|
||||||
type : 'post',
|
type : 'post',
|
||||||
data: params,
|
data: params,
|
||||||
@ -69,6 +69,8 @@ define('ajax', ['mailpoet', 'jquery'], function(MailPoet, jQuery) {
|
|||||||
|
|
||||||
// clear options
|
// clear options
|
||||||
this.options = {};
|
this.options = {};
|
||||||
|
|
||||||
|
return jqXHR;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -33,10 +33,14 @@ class Initializer {
|
|||||||
$subscribers = Env::$db_prefix . 'subscribers';
|
$subscribers = Env::$db_prefix . 'subscribers';
|
||||||
$settings = Env::$db_prefix . 'settings';
|
$settings = Env::$db_prefix . 'settings';
|
||||||
$newsletters = Env::$db_prefix . 'newsletters';
|
$newsletters = Env::$db_prefix . 'newsletters';
|
||||||
|
$segments = Env::$db_prefix . 'segments';
|
||||||
|
$subscriber_segment = Env::$db_prefix . 'subscriber_segment';
|
||||||
|
|
||||||
define('MP_SUBSCRIBERS_TABLE', $subscribers);
|
define('MP_SUBSCRIBERS_TABLE', $subscribers);
|
||||||
define('MP_SETTINGS_TABLE', $settings);
|
define('MP_SETTINGS_TABLE', $settings);
|
||||||
define('MP_NEWSLETTERS_TABLE', $newsletters);
|
define('MP_NEWSLETTERS_TABLE', $newsletters);
|
||||||
|
define('MP_SEGMENTS_TABLE', $segments);
|
||||||
|
define('MP_SUBSCRIBER_SEGMENT_TABLE', $subscriber_segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupActivator() {
|
function setupActivator() {
|
||||||
|
@ -12,7 +12,9 @@ class Migrator {
|
|||||||
$this->models = array(
|
$this->models = array(
|
||||||
'subscribers',
|
'subscribers',
|
||||||
'settings',
|
'settings',
|
||||||
'newsletters'
|
'newsletters',
|
||||||
|
'segments',
|
||||||
|
'subscriber_segment'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +80,30 @@ class Migrator {
|
|||||||
return $this->sqlify(__FUNCTION__, $attributes);
|
return $this->sqlify(__FUNCTION__, $attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function segments() {
|
||||||
|
$attributes = array(
|
||||||
|
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
||||||
|
'name varchar(90) NOT NULL,',
|
||||||
|
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
||||||
|
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||||
|
'PRIMARY KEY (id),',
|
||||||
|
'UNIQUE KEY name (name)'
|
||||||
|
);
|
||||||
|
return $this->sqlify(__FUNCTION__, $attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
function subscriber_segment() {
|
||||||
|
$attributes = array(
|
||||||
|
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
||||||
|
'subscriber_id mediumint(9) NOT NULL,',
|
||||||
|
'segment_id mediumint(9) NOT NULL,',
|
||||||
|
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
||||||
|
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||||
|
'PRIMARY KEY (id)'
|
||||||
|
);
|
||||||
|
return $this->sqlify(__FUNCTION__, $attributes);
|
||||||
|
}
|
||||||
|
|
||||||
private function sqlify($model, $attributes) {
|
private function sqlify($model, $attributes) {
|
||||||
$table = $this->prefix . $model;
|
$table = $this->prefix . $model;
|
||||||
|
|
||||||
|
35
lib/Models/Segment.php
Normal file
35
lib/Models/Segment.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Models;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class Segment extends Model {
|
||||||
|
public static $_table = MP_SEGMENTS_TABLE;
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->addValidations('name', array(
|
||||||
|
'required' => 'name_is_blank',
|
||||||
|
'isString' => 'name_is_not_string'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function createOrUpdate($model) {
|
||||||
|
$exists = self::where('name', $model['name'])
|
||||||
|
->find_one();
|
||||||
|
|
||||||
|
if($exists === false) {
|
||||||
|
$new_model = self::create();
|
||||||
|
$new_model->name = $model['name'];
|
||||||
|
return $new_model->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
$exists->name = $model['name_updated'];
|
||||||
|
return $exists->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function subscribers() {
|
||||||
|
return $this->has_many_through(__NAMESPACE__ . '\Subscriber', __NAMESPACE__ . '\SubscriberSegment', 'segment_id', 'subscriber_id');
|
||||||
|
}
|
||||||
|
}
|
@ -20,11 +20,11 @@ class Setting extends Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static function createOrUpdate($model) {
|
public static function createOrUpdate($model) {
|
||||||
$exists = Setting::where('name', $model['name'])
|
$exists = self::where('name', $model['name'])
|
||||||
->find_one();
|
->find_one();
|
||||||
|
|
||||||
if($exists === false) {
|
if($exists === false) {
|
||||||
$new_model = Setting::create();
|
$new_model = self::create();
|
||||||
$new_model->hydrate($model);
|
$new_model->hydrate($model);
|
||||||
return $new_model->save();
|
return $new_model->save();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace MailPoet\Models;
|
namespace MailPoet\Models;
|
||||||
|
|
||||||
if (!defined('ABSPATH')) exit;
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
class Subscriber extends Model {
|
class Subscriber extends Model {
|
||||||
public static $_table = MP_SUBSCRIBERS_TABLE;
|
public static $_table = MP_SUBSCRIBERS_TABLE;
|
||||||
@ -61,4 +61,8 @@ class Subscriber extends Model {
|
|||||||
|
|
||||||
return $orm->where('status', $group);
|
return $orm->where('status', $group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function segments() {
|
||||||
|
return $this->has_many_through(__NAMESPACE__ . '\Segment', __NAMESPACE__ . '\SubscriberSegment', 'subscriber_id', 'segment_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
12
lib/Models/SubscriberSegment.php
Normal file
12
lib/Models/SubscriberSegment.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Models;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class SubscriberSegment extends Model {
|
||||||
|
public static $_table = MP_SUBSCRIBER_SEGMENT_TABLE;
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
}
|
@ -7,12 +7,14 @@ require_once(getenv('WP_TEST_PATH') . '/wp-load.php');
|
|||||||
|
|
||||||
$console->writeln('Cleaning up database...');
|
$console->writeln('Cleaning up database...');
|
||||||
$models = array(
|
$models = array(
|
||||||
"Subscriber",
|
'Subscriber',
|
||||||
"Setting",
|
'Setting',
|
||||||
"Newsletter"
|
'Newsletter',
|
||||||
|
'Segment',
|
||||||
|
'SubscriberSegment'
|
||||||
);
|
);
|
||||||
$destroy = function ($model) {
|
$destroy = function ($model) {
|
||||||
Model::factory("\MailPoet\Models\\" . $model)
|
Model::factory('\MailPoet\Models\\' . $model)
|
||||||
->delete_many();
|
->delete_many();
|
||||||
};
|
};
|
||||||
array_map($destroy, $models);
|
array_map($destroy, $models);
|
||||||
|
120
tests/unit/Models/SegmentCest.php
Normal file
120
tests/unit/Models/SegmentCest.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use MailPoet\Models\SubscriberSegment;
|
||||||
|
use MailPoet\Models\Subscriber;
|
||||||
|
use MailPoet\Models\Segment;
|
||||||
|
|
||||||
|
class SegmentCest {
|
||||||
|
function _before() {
|
||||||
|
$this->before_time = time();
|
||||||
|
$this->data = array(
|
||||||
|
'name' => 'some name',
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->segment = Segment::create();
|
||||||
|
$this->segment->hydrate($this->data);
|
||||||
|
$this->saved = $this->segment->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanBeCreated() {
|
||||||
|
expect($this->saved)->equals(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itHasToBeValid() {
|
||||||
|
expect($this->saved)->equals(true);
|
||||||
|
$empty_model = Segment::create();
|
||||||
|
expect($empty_model->save())->equals(false);
|
||||||
|
$validations = $empty_model->getValidationErrors();
|
||||||
|
expect(count($validations))->equals(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itHasACreatedAtOnCreation() {
|
||||||
|
$segment = Segment::where('name', $this->data['name'])
|
||||||
|
->findOne();
|
||||||
|
$time_difference = strtotime($segment->created_at) >= $this->before_time;
|
||||||
|
expect($time_difference)->equals(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itHasAnUpdatedAtOnCreation() {
|
||||||
|
$segment = Segment::where('name', $this->data['name'])
|
||||||
|
->findOne();
|
||||||
|
$time_difference = strtotime($segment->updated_at) >= $this->before_time;
|
||||||
|
expect($time_difference)->equals(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itKeepsTheCreatedAtOnUpdate() {
|
||||||
|
$segment = Segment::where('name', $this->data['name'])
|
||||||
|
->findOne();
|
||||||
|
$old_created_at = $segment->created_at;
|
||||||
|
$segment->name = 'new name';
|
||||||
|
$segment->save();
|
||||||
|
expect($old_created_at)->equals($segment->created_at);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itUpdatesTheUpdatedAtOnUpdate() {
|
||||||
|
$segment = Segment::where('name', $this->data['name'])
|
||||||
|
->findOne();
|
||||||
|
$update_time = time();
|
||||||
|
$segment->name = 'new name';
|
||||||
|
$segment->save();
|
||||||
|
$time_difference = strtotime($segment->updated_at) >= $update_time;
|
||||||
|
expect($time_difference)->equals(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanCreateOrUpdate() {
|
||||||
|
$data = array(
|
||||||
|
'name' => 'some other new name'
|
||||||
|
);
|
||||||
|
$createNewRecord = Segment::createOrUpdate($data);
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'name' => $this->data['name'],
|
||||||
|
'name_updated' => 'updated name',
|
||||||
|
);
|
||||||
|
$updateExistingRecord = Segment::createOrUpdate($data);
|
||||||
|
|
||||||
|
$allRecords = Segment::find_array();
|
||||||
|
expect(count($allRecords))->equals(2);
|
||||||
|
expect($allRecords[0]['name'])->equals($data['name_updated']);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanHaveMultipleSubscribers() {
|
||||||
|
$subscribersData = array(
|
||||||
|
array(
|
||||||
|
'first_name' => 'John',
|
||||||
|
'last_name' => 'Mailer',
|
||||||
|
'email' => 'john@mailpoet.com'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'first_name' => 'Mike',
|
||||||
|
'last_name' => 'Smith',
|
||||||
|
'email' => 'mike@maipoet.com'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
foreach ($subscribersData as $subscriberData) {
|
||||||
|
$subscriber = Subscriber::create();
|
||||||
|
$subscriber->hydrate($subscriberData);
|
||||||
|
$subscriber->save();
|
||||||
|
$association = SubscriberSegment::create();
|
||||||
|
$association->subscriber_id = $subscriber->id;
|
||||||
|
$association->segment_id = $this->segment->id;
|
||||||
|
$association->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
$segment = Segment::find_one($this->segment->id);
|
||||||
|
$subscribers = $segment->subscribers()
|
||||||
|
->find_array();
|
||||||
|
expect(count($subscribers))->equals(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _after() {
|
||||||
|
ORM::for_table(Segment::$_table)
|
||||||
|
->delete_many();
|
||||||
|
ORM::for_table(Subscriber::$_table)
|
||||||
|
->delete_many();
|
||||||
|
ORM::for_table(SubscriberSegment::$_table)
|
||||||
|
->delete_many();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,32 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
|
use MailPoet\Models\Segment;
|
||||||
|
use MailPoet\Models\SubscriberSegment;
|
||||||
|
|
||||||
class SubscriberCest {
|
class SubscriberCest {
|
||||||
|
|
||||||
function _before() {
|
function _before() {
|
||||||
|
$this->before_time = time();
|
||||||
$this->data = array(
|
$this->data = array(
|
||||||
'first_name' => 'John',
|
'first_name' => 'John',
|
||||||
'last_name' => 'Mailer',
|
'last_name' => 'Mailer',
|
||||||
'email' => 'jo@mailpoet.com'
|
'email' => 'john@mailpoet.com'
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->subscriber = Subscriber::create();
|
$this->subscriber = Subscriber::create();
|
||||||
$this->subscriber->hydrate($this->data);
|
$this->subscriber->hydrate($this->data);
|
||||||
$this->saved = $this->subscriber->save();
|
$this->saved = $this->subscriber->save();
|
||||||
|
|
||||||
$subscribed = Subscriber::create();
|
|
||||||
$subscribed->hydrate(array(
|
|
||||||
'email' => 'marco@mailpoet.com',
|
|
||||||
'status' => 'subscribed'
|
|
||||||
));
|
|
||||||
$subscribed->save();
|
|
||||||
|
|
||||||
$unsubscribed = Subscriber::create();
|
|
||||||
$unsubscribed->hydrate(array(
|
|
||||||
'email' => 'marco@mailpoet.com',
|
|
||||||
'status' => 'unsubscribed'
|
|
||||||
));
|
|
||||||
$unsubscribed->save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function itCanBeCreated() {
|
function itCanBeCreated() {
|
||||||
@ -57,6 +46,13 @@ class SubscriberCest {
|
|||||||
->equals($this->data['email']);
|
->equals($this->data['email']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function emailMustBeUnique() {
|
||||||
|
$conflict_subscriber = Subscriber::create();
|
||||||
|
$conflict_subscriber->hydrate($this->data);
|
||||||
|
$saved = $conflict_subscriber->save();
|
||||||
|
expect($saved)->equals(false);
|
||||||
|
}
|
||||||
|
|
||||||
function itHasAStatus() {
|
function itHasAStatus() {
|
||||||
$subscriber =
|
$subscriber =
|
||||||
Subscriber::where('email', $this->data['email'])
|
Subscriber::where('email', $this->data['email'])
|
||||||
@ -105,15 +101,31 @@ class SubscriberCest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function emailMustBeUnique() {
|
function itCanHaveASegment() {
|
||||||
$conflict_subscriber = Subscriber::create();
|
$segmentData = array(
|
||||||
$conflict_subscriber->hydrate($this->data);
|
'name' => 'some name'
|
||||||
$saved = $conflict_subscriber->save();
|
);
|
||||||
expect($saved)->equals(false);
|
|
||||||
|
$segment = Segment::create();
|
||||||
|
$segment->hydrate($segmentData);
|
||||||
|
$segment->save();
|
||||||
|
$association = SubscriberSegment::create();
|
||||||
|
$association->subscriber_id = $this->subscriber->id;
|
||||||
|
$association->segment_id = $segment->id;
|
||||||
|
$association->save();
|
||||||
|
|
||||||
|
$subscriber = Subscriber::find_one($this->subscriber->id);
|
||||||
|
$subscriberSegment = $subscriber->segments()
|
||||||
|
->find_one();
|
||||||
|
expect($subscriberSegment->id)->equals($segment->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _after() {
|
function _after() {
|
||||||
ORM::for_table(Subscriber::$_table)
|
ORM::for_table(Subscriber::$_table)
|
||||||
->delete_many();
|
->delete_many();
|
||||||
|
ORM::for_table(Segment::$_table)
|
||||||
|
->delete_many();
|
||||||
|
ORM::for_table(SubscriberSegment::$_table)
|
||||||
|
->delete_many();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user