Optimized Bulk actions
- Updated SQL schema for every created_at column so that it has a default value - Updated unit tests based on recent changes (new methods in SubscriberSegment model) - Added check for HelpScout initialization code so that it doesn't throw errors
This commit is contained in:
@ -63,9 +63,9 @@ class Migrator {
|
||||
'name varchar(90) NOT NULL,',
|
||||
'type varchar(90) NOT NULL DEFAULT "default",',
|
||||
'description varchar(250) NOT NULL DEFAULT "",',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'deleted_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY name (name)'
|
||||
);
|
||||
@ -77,7 +77,7 @@ class Migrator {
|
||||
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
||||
'name varchar(20) NOT NULL,',
|
||||
'value longtext,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY name (name)'
|
||||
@ -91,7 +91,7 @@ class Migrator {
|
||||
'name varchar(90) NOT NULL,',
|
||||
'type varchar(90) NOT NULL,',
|
||||
'params longtext NOT NULL,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY name (name)'
|
||||
@ -114,8 +114,8 @@ class Migrator {
|
||||
'count_failed mediumint(9) NOT NULL DEFAULT 0,',
|
||||
'scheduled_at TIMESTAMP NULL,',
|
||||
'processed_at TIMESTAMP NULL,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'deleted_at TIMESTAMP NULL,',
|
||||
'PRIMARY KEY (id)',
|
||||
);
|
||||
@ -130,8 +130,8 @@ class Migrator {
|
||||
'last_name tinytext NOT NULL DEFAULT "",',
|
||||
'email varchar(150) NOT NULL,',
|
||||
'status varchar(12) NOT NULL DEFAULT "' . Subscriber::STATUS_UNCONFIRMED . '",',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'deleted_at TIMESTAMP NULL,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY email (email)'
|
||||
@ -145,8 +145,8 @@ class Migrator {
|
||||
'subscriber_id mediumint(9) NOT NULL,',
|
||||
'segment_id mediumint(9) NOT NULL,',
|
||||
'status varchar(12) NOT NULL DEFAULT "' . Subscriber::STATUS_SUBSCRIBED . '",',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY subscriber_segment (subscriber_id,segment_id)'
|
||||
);
|
||||
@ -159,8 +159,8 @@ class Migrator {
|
||||
'subscriber_id mediumint(9) NOT NULL,',
|
||||
'custom_field_id mediumint(9) NOT NULL,',
|
||||
'value varchar(255) NOT NULL DEFAULT "",',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY subscriber_id_custom_field_id (subscriber_id,custom_field_id)'
|
||||
);
|
||||
@ -178,8 +178,8 @@ class Migrator {
|
||||
'reply_to_name varchar(150) NOT NULL DEFAULT "",',
|
||||
'preheader varchar(250) NOT NULL DEFAULT "",',
|
||||
'body longtext,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'deleted_at TIMESTAMP NULL,',
|
||||
'PRIMARY KEY (id)'
|
||||
);
|
||||
@ -194,8 +194,8 @@ class Migrator {
|
||||
'body LONGTEXT,',
|
||||
'thumbnail LONGTEXT,',
|
||||
'readonly TINYINT(1) DEFAULT 0,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id)'
|
||||
);
|
||||
return $this->sqlify(__FUNCTION__, $attributes);
|
||||
@ -206,8 +206,8 @@ class Migrator {
|
||||
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
||||
'name varchar(90) NOT NULL,',
|
||||
'newsletter_type varchar(90) NOT NULL,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY name_newsletter_type (newsletter_type,name)'
|
||||
);
|
||||
@ -220,8 +220,8 @@ class Migrator {
|
||||
'newsletter_id mediumint(9) NOT NULL,',
|
||||
'option_field_id mediumint(9) NOT NULL,',
|
||||
'value varchar(255) NOT NULL DEFAULT "",',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY newsletter_id_option_field_id (newsletter_id,option_field_id)'
|
||||
);
|
||||
@ -233,8 +233,8 @@ class Migrator {
|
||||
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
||||
'newsletter_id mediumint(9) NOT NULL,',
|
||||
'segment_id mediumint(9) NOT NULL,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY newsletter_segment (newsletter_id,segment_id)'
|
||||
);
|
||||
@ -248,8 +248,8 @@ class Migrator {
|
||||
'queue_id mediumint(9) NOT NULL,',
|
||||
'url varchar(255) NOT NULL,',
|
||||
'hash varchar(20) NOT NULL,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id)',
|
||||
);
|
||||
return $this->sqlify(__FUNCTION__, $attributes);
|
||||
@ -260,7 +260,7 @@ class Migrator {
|
||||
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
||||
'newsletter_id mediumint(9) NOT NULL,',
|
||||
'post_id mediumint(9) NOT NULL,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id)',
|
||||
);
|
||||
@ -274,8 +274,8 @@ class Migrator {
|
||||
'body longtext,',
|
||||
'settings longtext,',
|
||||
'styles longtext,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'deleted_at TIMESTAMP NULL,',
|
||||
'PRIMARY KEY (id)'
|
||||
);
|
||||
@ -302,8 +302,8 @@ class Migrator {
|
||||
'queue_id mediumint(9) NOT NULL,',
|
||||
'link_id mediumint(9) NOT NULL,',
|
||||
'count mediumint(9) NOT NULL,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'updated_at TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id)',
|
||||
);
|
||||
return $this->sqlify(__FUNCTION__, $attributes);
|
||||
@ -315,7 +315,7 @@ class Migrator {
|
||||
'newsletter_id mediumint(9) NOT NULL,',
|
||||
'subscriber_id mediumint(9) NOT NULL,',
|
||||
'queue_id mediumint(9) NOT NULL,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id)',
|
||||
);
|
||||
return $this->sqlify(__FUNCTION__, $attributes);
|
||||
@ -327,7 +327,7 @@ class Migrator {
|
||||
'newsletter_id mediumint(9) NOT NULL,',
|
||||
'subscriber_id mediumint(9) NOT NULL,',
|
||||
'queue_id mediumint(9) NOT NULL,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id)',
|
||||
);
|
||||
return $this->sqlify(__FUNCTION__, $attributes);
|
||||
@ -338,7 +338,7 @@ class Migrator {
|
||||
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
|
||||
'form_id mediumint(9) NOT NULL,',
|
||||
'subscriber_id mediumint(9) NOT NULL,',
|
||||
'created_at TIMESTAMP NULL,',
|
||||
'created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,',
|
||||
'PRIMARY KEY (id),',
|
||||
'UNIQUE KEY form_subscriber (form_id,subscriber_id)'
|
||||
);
|
||||
|
@ -22,8 +22,17 @@ class BulkAction {
|
||||
}
|
||||
|
||||
function apply() {
|
||||
$bulk_action_method = 'bulk'.ucfirst($this->action);
|
||||
|
||||
if(!method_exists($this->model_class, $bulk_action_method)) {
|
||||
throw new Exception(
|
||||
$this->model_class. ' has not method "'.$bulk_action_method.'"'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return call_user_func_array(
|
||||
array($this->model_class, 'bulk'.ucfirst($this->action)),
|
||||
array($this->model_class, $bulk_action_method),
|
||||
array($this->listing->getSelection(), $this->data)
|
||||
);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Model extends \Sudzy\ValidModel {
|
||||
protected $_errors;
|
||||
const MAX_BATCH_SIZE = 200;
|
||||
|
||||
function __construct() {
|
||||
$this->_errors = array();
|
||||
@ -109,25 +110,50 @@ class Model extends \Sudzy\ValidModel {
|
||||
static function bulkAction($orm, $callback = false) {
|
||||
$total = $orm->count();
|
||||
|
||||
if($total > 0) {
|
||||
$models = $orm->select(static::$_table.'.id')
|
||||
if($total === 0) return false;
|
||||
|
||||
$affected_rows = 0;
|
||||
|
||||
if($total > self::MAX_BATCH_SIZE) {
|
||||
for(
|
||||
$i = 0, $batches = ceil($total / self::MAX_BATCH_SIZE);
|
||||
$i < $batches;
|
||||
$i++
|
||||
) {
|
||||
$rows = $orm->select('id')
|
||||
->offset($i * self::MAX_BATCH_SIZE)
|
||||
->limit(self::MAX_BATCH_SIZE)
|
||||
->findArray();
|
||||
|
||||
$ids = array_map(function($model) {
|
||||
return (int)$model['id'];
|
||||
}, $rows);
|
||||
|
||||
if($callback !== false) {
|
||||
$callback($ids);
|
||||
}
|
||||
|
||||
// increment number of affected rows
|
||||
$affected_rows += $orm->get_last_statement()->rowCount();
|
||||
}
|
||||
} else {
|
||||
$rows = $orm->select(static::$_table.'.id')
|
||||
->offset(null)
|
||||
->limit(null)
|
||||
->findArray();
|
||||
|
||||
$ids = array_map(function($model) {
|
||||
return (int)$model['id'];
|
||||
}, $models);
|
||||
}, $rows);
|
||||
|
||||
if(is_callable($callback)) {
|
||||
if($callback !== false) {
|
||||
$callback($ids);
|
||||
}
|
||||
|
||||
$last_statement = $orm->get_last_statement();
|
||||
return $last_statement->rowCount();
|
||||
// get number of affected rows
|
||||
$affected_rows = $orm->get_last_statement()->rowCount();
|
||||
}
|
||||
|
||||
return false;
|
||||
return $affected_rows;
|
||||
}
|
||||
|
||||
function duplicate($data = array()) {
|
||||
|
@ -498,54 +498,72 @@ class Subscriber extends Model {
|
||||
));
|
||||
}
|
||||
|
||||
static function bulkMoveToList($orm, $data = array()) {
|
||||
static function bulkAddToList($orm, $data = array()) {
|
||||
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
||||
$segment = Segment::findOne($segment_id);
|
||||
|
||||
if($segment !== false) {
|
||||
$subscribers_count = 0;
|
||||
$subscribers = $orm->findResultSet();
|
||||
foreach($subscribers as $subscriber) {
|
||||
SubscriberSegment::resetSubscriptions($subscriber, array($segment->id));
|
||||
$subscribers_count++;
|
||||
if($segment === false) return false;
|
||||
|
||||
$subscribers_count = parent::bulkAction($orm,
|
||||
function($subscriber_ids) use($segment) {
|
||||
SubscriberSegment::subscribeManyToSegments(
|
||||
$subscriber_ids, array($segment->id)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return array(
|
||||
'subscribers' => $subscribers_count,
|
||||
'segment' => $segment->name
|
||||
);
|
||||
}
|
||||
return false;
|
||||
|
||||
static function bulkMoveToList($orm, $data = array()) {
|
||||
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
||||
$segment = Segment::findOne($segment_id);
|
||||
|
||||
if($segment === false) return false;
|
||||
|
||||
$subscribers_count = parent::bulkAction($orm,
|
||||
function($subscriber_ids) use($segment) {
|
||||
SubscriberSegment::deleteManySubscriptions($subscriber_ids);
|
||||
SubscriberSegment::subscribeManyToSegments(
|
||||
$subscriber_ids, array($segment->id)
|
||||
);
|
||||
});
|
||||
|
||||
return array(
|
||||
'subscribers' => $subscribers_count,
|
||||
'segment' => $segment->name
|
||||
);
|
||||
}
|
||||
|
||||
static function bulkRemoveFromList($orm, $data = array()) {
|
||||
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
||||
$segment = Segment::findOne($segment_id);
|
||||
|
||||
if($segment !== false) {
|
||||
$subscribers_count = 0;
|
||||
if($segment === false) return false;
|
||||
|
||||
// delete relations with segment
|
||||
$subscribers = $orm->findResultSet();
|
||||
foreach($subscribers as $subscriber) {
|
||||
SubscriberSegment::unsubscribeFromSegments($subscriber, array($segment->id));
|
||||
$subscribers_count++;
|
||||
$subscribers_count = parent::bulkAction($orm,
|
||||
function($subscriber_ids) use($segment) {
|
||||
SubscriberSegment::deleteManySubscriptions(
|
||||
$subscriber_ids, array($segment->id)
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return array(
|
||||
'subscribers' => $subscribers_count,
|
||||
'segment' => $segment->name
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function bulkRemoveFromAllLists($orm) {
|
||||
$subscribers = $orm->findResultSet();
|
||||
$subscribers_count = 0;
|
||||
foreach($subscribers as $subscriber) {
|
||||
SubscriberSegment::unsubscribeFromSegments($subscriber);
|
||||
$subscribers_count++;
|
||||
}
|
||||
static function bulkRemoveFromAllLists($orm, $data = array()) {
|
||||
$subscribers_count = $orm->count();
|
||||
|
||||
parent::bulkAction($orm, function($subscriber_ids) {
|
||||
SubscriberSegment::deleteManySubscriptions($subscriber_ids);
|
||||
});
|
||||
|
||||
return $subscribers_count;
|
||||
}
|
||||
@ -567,31 +585,9 @@ class Subscriber extends Model {
|
||||
return false;
|
||||
}
|
||||
|
||||
static function bulkAddToList($orm, $data = array()) {
|
||||
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
||||
$segment = Segment::findOne($segment_id);
|
||||
|
||||
if($segment !== false) {
|
||||
$subscribers_count = 0;
|
||||
$subscribers = $orm->findMany();
|
||||
foreach($subscribers as $subscriber) {
|
||||
try {
|
||||
SubscriberSegment::subscribeToSegments($subscriber, array($segment->id));
|
||||
$subscribers_count++;
|
||||
} catch(Exception $e) {
|
||||
}
|
||||
}
|
||||
return array(
|
||||
'subscribers' => $subscribers_count,
|
||||
'segment' => $segment->name
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function bulkTrash($orm) {
|
||||
return parent::bulkAction($orm, function($subscriber_ids) use($orm) {
|
||||
parent::rawExecute(join(' ', array(
|
||||
return parent::bulkAction($orm, function($subscriber_ids) {
|
||||
self::rawExecute(join(' ', array(
|
||||
'UPDATE `'.self::$_table.'`',
|
||||
'SET `deleted_at` = NOW()',
|
||||
'WHERE `id` IN ('.rtrim(str_repeat('?,', count($subscriber_ids)), ',').')',
|
||||
|
@ -17,7 +17,7 @@ class SubscriberSegment extends Model {
|
||||
}
|
||||
|
||||
static function unsubscribeFromSegments($subscriber, $segment_ids = array()) {
|
||||
if($subscriber !== false && $subscriber->id > 0) {
|
||||
if($subscriber === false) return false;
|
||||
|
||||
$wp_segment = Segment::getWPSegment();
|
||||
|
||||
@ -57,13 +57,11 @@ class SubscriberSegment extends Model {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function subscribeToSegments($subscriber, $segment_ids = array()) {
|
||||
if($subscriber->id > 0) {
|
||||
if($subscriber === false) return false;
|
||||
if(!empty($segment_ids)) {
|
||||
// subscribe to segments
|
||||
// subscribe to specified segments
|
||||
foreach($segment_ids as $segment_id) {
|
||||
if((int)$segment_id > 0) {
|
||||
self::createOrUpdate(array(
|
||||
@ -75,25 +73,48 @@ class SubscriberSegment extends Model {
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// subscribe to all segments
|
||||
// (re)subscribe to all segments linked to the subscriber
|
||||
return self::where('subscriber_id', $subscriber->id)
|
||||
->findResultSet()
|
||||
->set('status', Subscriber::STATUS_SUBSCRIBED)
|
||||
->save();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function resetSubscriptions($subscriber, $segment_ids = array()) {
|
||||
self::unsubscribeFromSegments($subscriber);
|
||||
return self::subscribeToSegments($subscriber, $segment_ids);
|
||||
}
|
||||
|
||||
static function deleteManySubscriptions($subscriber_ids = array()) {
|
||||
if(!empty($subscriber_ids)) {
|
||||
// delete subscribers' relations to segments (except WP Users' segment)
|
||||
$subscriptions = SubscriberSegment::whereIn(
|
||||
static function subscribeManyToSegments(
|
||||
$subscriber_ids = array(),
|
||||
$segment_ids = array()
|
||||
) {
|
||||
if(empty($subscriber_ids) || empty($segment_ids)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// create many subscriptions to each segment
|
||||
foreach($segment_ids as $segment_id) {
|
||||
$query = array(
|
||||
'INSERT IGNORE INTO `'.self::$_table.'`',
|
||||
'(`subscriber_id`, `segment_id`, `status`)',
|
||||
'VALUES '.rtrim(str_repeat(
|
||||
"(?, ".(int)$segment_id.", '".Subscriber::STATUS_SUBSCRIBED."'), ",
|
||||
count($subscriber_ids)
|
||||
), ', ')
|
||||
);
|
||||
self::rawExecute(join(' ', $query), $subscriber_ids);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static function deleteManySubscriptions($subscriber_ids = array(), $segment_ids = array()) {
|
||||
if(empty($subscriber_ids)) return false;
|
||||
|
||||
// delete subscribers' relations to segments (except WP segment)
|
||||
$subscriptions = self::whereIn(
|
||||
'subscriber_id', $subscriber_ids
|
||||
);
|
||||
|
||||
@ -105,15 +126,19 @@ class SubscriberSegment extends Model {
|
||||
}
|
||||
return $subscriptions->deleteMany();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static function deleteSubscriptions($subscriber) {
|
||||
if($subscriber !== false && $subscriber->id > 0) {
|
||||
// delete all relationships to segments
|
||||
return self::where('subscriber_id', $subscriber->id)->deleteMany();
|
||||
static function deleteSubscriptions($subscriber, $segment_ids = array()) {
|
||||
if($subscriber === false) return false;
|
||||
|
||||
$wp_segment = Segment::getWPSegment();
|
||||
|
||||
$subscriptions = self::where('subscriber_id', $subscriber->id)
|
||||
->whereNotEqual('segment_id', $wp_segment->id);
|
||||
|
||||
if(!empty($segment_ids)) {
|
||||
$subscriptions = $subscriptions->whereIn('segment_id', $segment_ids);
|
||||
}
|
||||
return false;
|
||||
return $subscriptions->deleteMany();
|
||||
}
|
||||
|
||||
static function subscribed($orm) {
|
||||
@ -143,27 +168,4 @@ class SubscriberSegment extends Model {
|
||||
|
||||
return $subscription->save();
|
||||
}
|
||||
|
||||
// TO BE REVIEWED
|
||||
static function createMultiple($segmnets, $subscribers) {
|
||||
$values = Helpers::flattenArray(
|
||||
array_map(function ($segment) use ($subscribers) {
|
||||
return array_map(function ($subscriber) use ($segment) {
|
||||
return array(
|
||||
$segment,
|
||||
$subscriber
|
||||
);
|
||||
}, $subscribers);
|
||||
}, $segmnets)
|
||||
);
|
||||
return self::rawExecute(
|
||||
'INSERT IGNORE INTO `' . self::$_table . '` ' .
|
||||
'(segment_id, subscriber_id) ' .
|
||||
'VALUES ' . rtrim(
|
||||
str_repeat(
|
||||
'(?, ?), ', count($subscribers) * count($segmnets)), ', '
|
||||
),
|
||||
$values
|
||||
);
|
||||
}
|
||||
}
|
@ -361,9 +361,11 @@ class Import {
|
||||
return array_walk($wp_users, '\MailPoet\Segments\WP::synchronizeUser');
|
||||
}
|
||||
|
||||
function addSubscribersToSegments($subscribers, $segments) {
|
||||
foreach(array_chunk($subscribers, 200) as $data) {
|
||||
SubscriberSegment::createMultiple($segments, $data);
|
||||
function addSubscribersToSegments($subscriber_ids, $segment_ids) {
|
||||
foreach(array_chunk($subscriber_ids, 200) as $subscriber_ids_chunk) {
|
||||
SubscriberSegment::subscribeManyToSegments(
|
||||
$subscriber_ids_chunk, $segment_ids
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ class SubscriberSegmentTest extends MailPoetTest {
|
||||
expect($subscribed_segments[0]['name'])->equals($this->wp_segment->name);
|
||||
}
|
||||
|
||||
function testItCanDeleteSubscriptionToWPSegment() {
|
||||
function testItCannotDeleteSubscriptionToWPSegment() {
|
||||
// subscribe to a segment and the WP segment
|
||||
$result = SubscriberSegment::subscribeToSegments($this->subscriber, array(
|
||||
$this->segment_1->id,
|
||||
@ -235,11 +235,10 @@ class SubscriberSegmentTest extends MailPoetTest {
|
||||
$result = SubscriberSegment::deleteSubscriptions($this->subscriber);
|
||||
expect($result)->true();
|
||||
|
||||
// it should have removed all subscriptions (even to the WP segment)
|
||||
$subscriptions_count = SubscriberSegment::where(
|
||||
'subscriber_id', $this->subscriber->id
|
||||
)->count();
|
||||
expect($subscriptions_count)->equals(0);
|
||||
// the subscriber should still be subscribed to the WP segment
|
||||
$subscribed_segments = $this->subscriber->segments()->findArray();
|
||||
expect($subscribed_segments)->count(1);
|
||||
expect($subscribed_segments[0]['name'])->equals($this->wp_segment->name);
|
||||
}
|
||||
|
||||
function _after() {
|
||||
|
@ -390,38 +390,45 @@ class SubscriberTest extends MailPoetTest {
|
||||
}
|
||||
|
||||
function testItCanGetOnlySubscribedSubscribersInSegments() {
|
||||
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
||||
$columns = array(
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'status'
|
||||
);
|
||||
$values = array(
|
||||
array(
|
||||
$subscriber_1 = Subscriber::createOrUpdate(array(
|
||||
'first_name' => 'Adam',
|
||||
'last_name' => 'Smith',
|
||||
'email' => 'adam@smith.com',
|
||||
'status' => 'unconfirmed'
|
||||
),
|
||||
array(
|
||||
'status' => Subscriber::STATUS_UNCONFIRMED
|
||||
));
|
||||
|
||||
$subscriber_2 = Subscriber::createOrUpdate(array(
|
||||
'first_name' => 'Mary',
|
||||
'last_name' => 'Jane',
|
||||
'email' => 'mary@jane.com',
|
||||
'status' => 'subscribed'
|
||||
)
|
||||
'status' => Subscriber::STATUS_SUBSCRIBED
|
||||
));
|
||||
|
||||
$segment = Segment::createOrUpdate(array(
|
||||
'name' => 'Only Subscribed Subscribers Segment'
|
||||
));
|
||||
|
||||
//Subscriber::createMultiple($columns, $values);
|
||||
$result = SubscriberSegment::subscribeManyToSegments(
|
||||
array($subscriber_1->id, $subscriber_2->id),
|
||||
array($segment->id)
|
||||
);
|
||||
Subscriber::createMultiple($columns, $values);
|
||||
SubscriberSegment::createMultiple(array(1), array(1,2));
|
||||
$subscribed_subscribers_in_segment =
|
||||
Subscriber::getSubscribedInSegments(array(1))->findArray();
|
||||
expect(count($subscribed_subscribers_in_segment))->equals(1);
|
||||
$subscriber = Subscriber::findOne(1);
|
||||
$subscriber->status = 'subscribed';
|
||||
expect($result)->true();
|
||||
|
||||
$subscribed_subscribers_in_segment = Subscriber::getSubscribedInSegments(
|
||||
array($segment->id)
|
||||
)->findArray();
|
||||
expect($subscribed_subscribers_in_segment)->count(1);
|
||||
|
||||
// update 1st subscriber's state to subscribed
|
||||
$subscriber = Subscriber::findOne($subscriber_1->id);
|
||||
$subscriber->status = Subscriber::STATUS_SUBSCRIBED;
|
||||
$subscriber->save();
|
||||
$subscribed_subscribers_in_segment =
|
||||
Subscriber::getSubscribedInSegments(array(1))->findArray();
|
||||
expect(count($subscribed_subscribers_in_segment))->equals(2);
|
||||
|
||||
$subscribed_subscribers_in_segment = Subscriber::getSubscribedInSegments(
|
||||
array($segment->id)
|
||||
)->findArray();
|
||||
expect($subscribed_subscribers_in_segment)->count(2);
|
||||
}
|
||||
|
||||
function testItCannotTrashAWPUser() {
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\SubscriberCustomField;
|
||||
use MailPoet\Models\SubscriberSegment;
|
||||
use MailPoet\Subscribers\ImportExport\Import\Import;
|
||||
@ -40,7 +41,9 @@ class ImportTest extends MailPoetTest {
|
||||
'last_name',
|
||||
'email'
|
||||
);
|
||||
$this->segments = range(0, 1);
|
||||
$this->segment_1 = Segment::createOrUpdate(array('name' => 'Segment 1'));
|
||||
$this->segment_2 = Segment::createOrUpdate(array('name' => 'Segment 2'));
|
||||
|
||||
$this->subscriber_custom_fields = array(777);
|
||||
$this->import = new Import($this->data);
|
||||
$this->subscribers_data = $this->import->transformSubscribersData(
|
||||
@ -224,7 +227,7 @@ class ImportTest extends MailPoetTest {
|
||||
expect(count($db_subscribers))->equals(2);
|
||||
$this->import->addSubscribersToSegments(
|
||||
$db_subscribers,
|
||||
$this->segments
|
||||
array($this->segment_1->id, $this->segment_2->id)
|
||||
);
|
||||
$subscribers_segments = SubscriberSegment::findArray();
|
||||
expect(count($subscribers_segments))->equals(4);
|
||||
@ -277,7 +280,7 @@ class ImportTest extends MailPoetTest {
|
||||
}
|
||||
|
||||
|
||||
function testItCanaddSubscribersToSegments() {
|
||||
function testItCanAddSubscribersToSegments() {
|
||||
$subscribers_data = $this->subscribers_data;
|
||||
$this->import->createOrUpdateSubscribers(
|
||||
'create',
|
||||
@ -292,7 +295,7 @@ class ImportTest extends MailPoetTest {
|
||||
);
|
||||
$this->import->addSubscribersToSegments(
|
||||
$db_subscribers,
|
||||
$this->segments
|
||||
array($this->segment_1->id, $this->segment_2->id)
|
||||
);
|
||||
$subscribers_segments = SubscriberSegment::findArray();
|
||||
// 2 subscribers * 2 segments
|
||||
|
@ -52,14 +52,14 @@ jQuery('.toplevel_page_mailpoet.menu-top-last')
|
||||
|
||||
<script type="text/javascript">
|
||||
var mailpoet_date_format = "<%= wp_datetime_format() %>";
|
||||
</script>
|
||||
|
||||
<script>
|
||||
if(window['HS'] !== undefined) {
|
||||
HS.beacon.config({
|
||||
icon: 'message',
|
||||
zIndex: 50000,
|
||||
instructions: '<%= __('Want to give feedback to the MailPoet team? Write them right here with as much information as possible.') %>',
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<% block after_javascript %><% endblock %>
|
||||
|
Reference in New Issue
Block a user