Add 'Bounced' status to subscribers [MAILPOET-684]
Fix SubscriberTest->testItHasGroupFilter() making only one of four assertions due to lack of data. Fix a small issue with Import. Unexpected values for the status field were converted to 'unconfirmed' rather than 'subscribed' due to non-strict comparison in in_array(). This hindered 'bounced' status import as well.
This commit is contained in:
@ -28,6 +28,10 @@ var columns = [
|
||||
name: 'unsubscribed',
|
||||
label: MailPoet.I18n.t('unsubscribed')
|
||||
},
|
||||
{
|
||||
name: 'bounced',
|
||||
label: MailPoet.I18n.t('bounced')
|
||||
},
|
||||
{
|
||||
name: 'created_at',
|
||||
label: MailPoet.I18n.t('createdOn'),
|
||||
@ -192,6 +196,7 @@ const SegmentList = React.createClass({
|
||||
const subscribed = ~~(segment.subscribers_count.subscribed || 0);
|
||||
const unconfirmed = ~~(segment.subscribers_count.unconfirmed || 0);
|
||||
const unsubscribed = ~~(segment.subscribers_count.unsubscribed || 0);
|
||||
const bounced = ~~(segment.subscribers_count.bounced || 0);
|
||||
|
||||
let segment_name;
|
||||
|
||||
@ -229,6 +234,9 @@ const SegmentList = React.createClass({
|
||||
<td className="column-date" data-colname={ MailPoet.I18n.t('unsubscribed') }>
|
||||
<abbr>{ unsubscribed.toLocaleString() }</abbr>
|
||||
</td>
|
||||
<td className="column-date" data-colname={ MailPoet.I18n.t('bounced') }>
|
||||
<abbr>{ bounced.toLocaleString() }</abbr>
|
||||
</td>
|
||||
<td className="column-date" data-colname={ MailPoet.I18n.t('createdOn') }>
|
||||
<abbr>{ MailPoet.Date.format(segment.created_at) }</abbr>
|
||||
</td>
|
||||
|
@ -45,7 +45,8 @@ define(
|
||||
values: {
|
||||
'subscribed': MailPoet.I18n.t('subscribed'),
|
||||
'unconfirmed': MailPoet.I18n.t('unconfirmed'),
|
||||
'unsubscribed': MailPoet.I18n.t('unsubscribed')
|
||||
'unsubscribed': MailPoet.I18n.t('unsubscribed'),
|
||||
'bounced': MailPoet.I18n.t('bounced')
|
||||
},
|
||||
filter: function(subscriber, value) {
|
||||
if (~~(subscriber.wp_user_id) > 0 && value === 'unconfirmed') {
|
||||
|
@ -255,6 +255,10 @@ const SubscriberList = React.createClass({
|
||||
case 'unsubscribed':
|
||||
status = MailPoet.I18n.t('unsubscribed');
|
||||
break;
|
||||
|
||||
case 'bounced':
|
||||
status = MailPoet.I18n.t('bounced');
|
||||
break;
|
||||
}
|
||||
|
||||
let segments = false;
|
||||
|
@ -87,6 +87,10 @@ class Segment extends Model {
|
||||
'SUM(CASE subscribers.status WHEN "' . Subscriber::STATUS_UNCONFIRMED . '" THEN 1 ELSE 0 END)',
|
||||
Subscriber::STATUS_UNCONFIRMED
|
||||
)
|
||||
->select_expr(
|
||||
'SUM(CASE subscribers.status WHEN "' . Subscriber::STATUS_BOUNCED . '" THEN 1 ELSE 0 END)',
|
||||
Subscriber::STATUS_BOUNCED
|
||||
)
|
||||
->findOne()
|
||||
->asArray();
|
||||
|
||||
|
@ -13,6 +13,7 @@ class Subscriber extends Model {
|
||||
const STATUS_SUBSCRIBED = 'subscribed';
|
||||
const STATUS_UNSUBSCRIBED = 'unsubscribed';
|
||||
const STATUS_UNCONFIRMED = 'unconfirmed';
|
||||
const STATUS_BOUNCED = 'bounced';
|
||||
|
||||
const SUBSCRIPTION_LIMIT_COOLDOWN = 60;
|
||||
|
||||
@ -335,6 +336,11 @@ class Subscriber extends Model {
|
||||
'label' => __('Unsubscribed', 'mailpoet'),
|
||||
'count' => self::filter(self::STATUS_UNSUBSCRIBED)->count()
|
||||
),
|
||||
array(
|
||||
'name' => self::STATUS_BOUNCED,
|
||||
'label' => __('Bounced', 'mailpoet'),
|
||||
'count' => self::filter(self::STATUS_BOUNCED)->count()
|
||||
),
|
||||
array(
|
||||
'name' => 'trash',
|
||||
'label' => __('Trash', 'mailpoet'),
|
||||
@ -720,6 +726,12 @@ class Subscriber extends Model {
|
||||
->where('status', self::STATUS_UNCONFIRMED);
|
||||
}
|
||||
|
||||
static function bounced($orm) {
|
||||
return $orm
|
||||
->whereNull('deleted_at')
|
||||
->where('status', self::STATUS_BOUNCED);
|
||||
}
|
||||
|
||||
static function withoutSegments($orm) {
|
||||
return $orm->select(MP_SUBSCRIBERS_TABLE.'.*')
|
||||
->leftOuterJoin(
|
||||
|
@ -302,18 +302,24 @@ class Import {
|
||||
-1,
|
||||
'-1',
|
||||
'false'
|
||||
),
|
||||
'bounced' => array(
|
||||
'bounced'
|
||||
)
|
||||
);
|
||||
$subscribers_data['status'] = array_map(function($state) use ($statuses) {
|
||||
if(in_array(strtolower($state), $statuses['subscribed'])) {
|
||||
if(in_array(strtolower($state), $statuses['subscribed'], true)) {
|
||||
return 'subscribed';
|
||||
}
|
||||
if(in_array(strtolower($state), $statuses['unsubscribed'])) {
|
||||
if(in_array(strtolower($state), $statuses['unsubscribed'], true)) {
|
||||
return 'unsubscribed';
|
||||
}
|
||||
if(in_array(strtolower($state), $statuses['unconfirmed'])) {
|
||||
if(in_array(strtolower($state), $statuses['unconfirmed'], true)) {
|
||||
return 'unconfirmed';
|
||||
}
|
||||
if(in_array(strtolower($state), $statuses['bounced'], true)) {
|
||||
return 'bounced';
|
||||
}
|
||||
return 'subscribed'; // make "subscribed" a default status
|
||||
}, $subscribers_data['status']);
|
||||
return array(
|
||||
|
@ -290,6 +290,14 @@ class Pages {
|
||||
'is_checked' => (
|
||||
$subscriber->status === Subscriber::STATUS_UNSUBSCRIBED
|
||||
)
|
||||
),
|
||||
array(
|
||||
'value' => array(
|
||||
Subscriber::STATUS_BOUNCED => __('Bounced', 'mailpoet')
|
||||
),
|
||||
'is_checked' => (
|
||||
$subscriber->status === Subscriber::STATUS_BOUNCED
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
0
testItHasGroupFilter
Normal file
0
testItHasGroupFilter
Normal file
@ -5,7 +5,7 @@ use \MailPoet\Models\Subscriber;
|
||||
|
||||
class BeaconTest extends MailPoetTest {
|
||||
function _before() {
|
||||
// create 3 users (1 confirmed, 1 subscribed, 1 unsubscribed)
|
||||
// create 4 users (1 confirmed, 1 subscribed, 1 unsubscribed, 1 bounced)
|
||||
Subscriber::createOrUpdate(array(
|
||||
'email' => 'user1@mailpoet.com',
|
||||
'status' => Subscriber::STATUS_SUBSCRIBED
|
||||
@ -18,6 +18,10 @@ class BeaconTest extends MailPoetTest {
|
||||
'email' => 'user3@mailpoet.com',
|
||||
'status' => Subscriber::STATUS_UNSUBSCRIBED
|
||||
));
|
||||
Subscriber::createOrUpdate(array(
|
||||
'email' => 'user4@mailpoet.com',
|
||||
'status' => Subscriber::STATUS_BOUNCED
|
||||
));
|
||||
|
||||
$this->beacon_data = Beacon::getData();
|
||||
}
|
||||
|
@ -114,16 +114,30 @@ class SubscriberTest extends MailPoetTest {
|
||||
foreach($subscribers as $subscriber) {
|
||||
expect($subscriber->status)->equals(Subscriber::STATUS_UNCONFIRMED);
|
||||
}
|
||||
|
||||
$this->subscriber->status = Subscriber::STATUS_SUBSCRIBED;
|
||||
$this->subscriber->save();
|
||||
$subscribers = Subscriber::filter('groupBy', Subscriber::STATUS_SUBSCRIBED)
|
||||
->findMany();
|
||||
foreach($subscribers as $subscriber) {
|
||||
expect($subscriber->status)->equals(Subscriber::STATUS_SUBSCRIBED);
|
||||
}
|
||||
|
||||
$this->subscriber->status = Subscriber::STATUS_UNSUBSCRIBED;
|
||||
$this->subscriber->save();
|
||||
$subscribers = Subscriber::filter('groupBy', Subscriber::STATUS_UNSUBSCRIBED)
|
||||
->findMany();
|
||||
foreach($subscribers as $subscriber) {
|
||||
expect($subscriber->status)->equals(Subscriber::STATUS_UNSUBSCRIBED);
|
||||
}
|
||||
|
||||
$this->subscriber->status = Subscriber::STATUS_BOUNCED;
|
||||
$this->subscriber->save();
|
||||
$subscribers = Subscriber::filter('groupBy', Subscriber::STATUS_BOUNCED)
|
||||
->findMany();
|
||||
foreach($subscribers as $subscriber) {
|
||||
expect($subscriber->status)->equals(Subscriber::STATUS_BOUNCED);
|
||||
}
|
||||
}
|
||||
|
||||
function testItCanHaveSegment() {
|
||||
@ -507,6 +521,11 @@ class SubscriberTest extends MailPoetTest {
|
||||
'deleted_at' => Carbon::now()->toDateTimeString()
|
||||
));
|
||||
|
||||
$subscriber_5 = Subscriber::createOrUpdate(array(
|
||||
'email' => 'subscriber_5@mailpoet.com',
|
||||
'status' => Subscriber::STATUS_BOUNCED
|
||||
));
|
||||
|
||||
// counts only subscribed & unconfirmed users
|
||||
$total = Subscriber::getTotalSubscribers();
|
||||
expect($total)->equals(2);
|
||||
|
@ -153,7 +153,12 @@ class ShortcodesTest extends MailPoetTest {
|
||||
$this->subscriber->save();
|
||||
$result =
|
||||
$shortcodes_object->process(array('[subscriber:count]'));
|
||||
expect($result[0])->equals(--$subscriber_count);
|
||||
expect($result[0])->equals($subscriber_count - 1);
|
||||
$this->subscriber->status = 'bounced';
|
||||
$this->subscriber->save();
|
||||
$result =
|
||||
$shortcodes_object->process(array('[subscriber:count]'));
|
||||
expect($result[0])->equals($subscriber_count - 1);
|
||||
}
|
||||
|
||||
function testItCanProcessSubscriberCustomFieldShortcodes() {
|
||||
|
@ -186,7 +186,12 @@ class ImportTest extends MailPoetTest {
|
||||
'unsubscribed',
|
||||
-1,
|
||||
'-1',
|
||||
'false'
|
||||
'false',
|
||||
#bounced
|
||||
'bounced',
|
||||
#unexpected
|
||||
'qwerty',
|
||||
null
|
||||
),
|
||||
);
|
||||
list($subscribers_data, $subsciber_fields) =
|
||||
@ -205,7 +210,10 @@ class ImportTest extends MailPoetTest {
|
||||
'unsubscribed',
|
||||
'unsubscribed',
|
||||
'unsubscribed',
|
||||
'unsubscribed'
|
||||
'unsubscribed',
|
||||
'bounced',
|
||||
'subscribed',
|
||||
'subscribed'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -30,6 +30,7 @@
|
||||
'subscribed': __('Subscribed'),
|
||||
'unconfirmed': __('Unconfirmed'),
|
||||
'unsubscribed': __('Unsubscribed'),
|
||||
'bounced': __('Bounced'),
|
||||
'createdOn': __('Created on'),
|
||||
'oneSegmentTrashed': __('1 list was moved to the trash'),
|
||||
'multipleSegmentsTrashed': __('%$1d lists were moved to the trash'),
|
||||
|
@ -50,6 +50,7 @@
|
||||
'unconfirmed': __('Unconfirmed'),
|
||||
'subscribed': __('Subscribed'),
|
||||
'unsubscribed': __('Unsubscribed'),
|
||||
'bounced': __('Bounced'),
|
||||
'selectList': __('Select a list'),
|
||||
'unsubscribedOn': __('Unsubscribed on %$1s'),
|
||||
'subscriberUpdated': __('Subscriber was updated successfully!'),
|
||||
|
Reference in New Issue
Block a user