adding subscribers getter from dynamic segments

This commit is contained in:
Amine Ben hammou
2018-03-15 17:56:10 +01:00
parent ca9e11a231
commit 1af242c2dd
5 changed files with 170 additions and 64 deletions

View File

@ -9,63 +9,25 @@ use MailPoet\Models\SubscriberSegment;
/** /**
* Gets batches of subscribers from default segments. * Gets batches of subscribers from default segments.
*/ */
class DefaultSubscribersGetter { class DefaultSubscribersGetter extends SubscribersGetter {
protected $segments_ids; /**
protected $batch_size; * @var bool
protected $offset; */
protected $finished;
protected $get_subscribers_without_segment; protected $get_subscribers_without_segment;
public function __construct($segments_ids, $batch_size) { public function __construct($segments_ids, $batch_size) {
parent::__construct($segments_ids, $batch_size);
$this->get_subscribers_without_segment = (array_search(0, $segments_ids) !== false); $this->get_subscribers_without_segment = (array_search(0, $segments_ids) !== false);
$this->segments_ids = $this->filterSegmentIds($segments_ids);
$this->batch_size = $batch_size;
$this->reset();
} }
protected function filterSegmentIds($ids) { protected function filter($subscribers) {
$ids = array_map(function($data) { $subscribers = $subscribers
return $data['id']; ->selectMany(
}, Segment::select('id') array(
->whereIn('id', $ids) 'list_status' => SubscriberSegment::$_table . '.status'
->where('type', Segment::TYPE_DEFAULT) )
->findArray()
);
if($this->get_subscribers_without_segment) {
$ids[] = 0;
}
return $ids;
}
public function reset() {
$this->offset = 0;
$this->finished = false;
}
/**
* Gets the next batch of subscribers or `false` if no more!
*/
public function get() {
if($this->finished) {
return false;
}
// define returned columns
$subscribers = Subscriber::selectMany(
'first_name',
'last_name',
'email',
'subscribed_ip',
array(
'global_status' => Subscriber::$_table . '.status'
),
array(
'list_status' => SubscriberSegment::$_table . '.status'
) )
);
// JOIN subscribers on segment and subscriber_segment tables
$subscribers = $subscribers
->left_outer_join( ->left_outer_join(
SubscriberSegment::$_table, SubscriberSegment::$_table,
array( array(
@ -82,7 +44,6 @@ class DefaultSubscribersGetter {
SubscriberSegment::$_table . '.segment_id' SubscriberSegment::$_table . '.segment_id'
) )
) )
->filter('filterWithCustomFieldsForExport')
->groupBy(Subscriber::$_table . '.id') ->groupBy(Subscriber::$_table . '.id')
->groupBy(Segment::$_table . '.id'); ->groupBy(Segment::$_table . '.id');
@ -107,18 +68,13 @@ class DefaultSubscribersGetter {
->selectExpr('MAX(' . Segment::$_table . '.name) as segment_name') ->selectExpr('MAX(' . Segment::$_table . '.name) as segment_name')
->whereIn(SubscriberSegment::$_table . '.segment_id', $this->segments_ids); ->whereIn(SubscriberSegment::$_table . '.segment_id', $this->segments_ids);
} }
$subscribers = $subscribers $subscribers = $subscribers
->whereNull(Subscriber::$_table . '.deleted_at')
->offset($this->offset) ->offset($this->offset)
->limit($this->batch_size) ->limit($this->batch_size)
->findArray(); ->findArray();
$this->offset += $this->batch_size;
if(count($subscribers) < $this->batch_size) {
$this->finished = true;
}
return $subscribers; return $subscribers;
} }
} }

View File

@ -0,0 +1,65 @@
<?php
namespace MailPoet\Subscribers\ImportExport\Export;
use MailPoet\Models\Segment;
use MailPoet\Models\Subscriber;
use MailPoet\WP\Hooks;
/**
* Gets batches of subscribers from dynamic segments.
*/
class DynamicSubscribersGetter extends SubscribersGetter {
protected $segment_index;
public function reset() {
parent::reset();
$this->segment_index = 0;
}
protected function filter($subscribers) {
$segment_id = $this->segments_ids[$this->segment_index];
$filters = Hooks::applyFilters(
'mailpoet_add_segment_filters',
$segment_id
);
if(!is_array($filters) || empty($filters)) {
return array();
}
$name = Segment::findOne($segment_id)->name;
foreach($filters as $filter) {
$subscribers = $filter->toSql($subscribers);
}
return $subscribers
->selectMany(array(
'list_status' => Subscriber::$_table . '.status'
))
->selectExpr("'{$name}' AS segment_name")
->offset($this->offset)
->limit($this->batch_size)
->findArray();
}
public function get() {
if($this->segment_index >= count($this->segments_ids)) {
$this->finished = true;
}
$subscribers = parent::get();
if($subscribers !== false && count($subscribers) < $this->batch_size) {
$this->segment_index ++;
$this->offset = 0;
$this->finished = false;
}
return $subscribers;
}
}

View File

@ -23,6 +23,7 @@ class Export {
public $export_file; public $export_file;
public $export_file_URL; public $export_file_URL;
public $default_subscribers_getter; public $default_subscribers_getter;
public $dynamic_subscribers_getter;
public function __construct($data) { public function __construct($data) {
if(strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { if(strpos(@ini_get('disable_functions'), 'set_time_limit') === false) {
@ -34,6 +35,11 @@ class Export {
self::SUBSCRIBER_BATCH_SIZE self::SUBSCRIBER_BATCH_SIZE
); );
$this->dynamic_subscribers_getter = new DynamicSubscribersGetter(
$data['segments'],
self::SUBSCRIBER_BATCH_SIZE
);
$this->export_format_option = $data['export_format_option']; $this->export_format_option = $data['export_format_option'];
$this->subscriber_fields = $data['subscriber_fields']; $this->subscriber_fields = $data['subscriber_fields'];
$this->subscriber_custom_fields = $this->getSubscriberCustomFields(); $this->subscriber_custom_fields = $this->getSubscriberCustomFields();
@ -162,6 +168,9 @@ class Export {
function getSubscribers() { function getSubscribers() {
$subscribers = $this->default_subscribers_getter->get(); $subscribers = $this->default_subscribers_getter->get();
if($subscribers === false) {
$subscribers = $this->dynamic_subscribers_getter->get();
}
return $subscribers; return $subscribers;
} }

View File

@ -0,0 +1,74 @@
<?php
namespace MailPoet\Subscribers\ImportExport\Export;
use MailPoet\Models\Subscriber;
/**
* Gets batches of subscribers for export.
*/
abstract class SubscribersGetter {
protected $segments_ids;
protected $batch_size;
protected $offset;
protected $finished;
public function __construct($segments_ids, $batch_size) {
$this->segments_ids = $segments_ids;
$this->batch_size = $batch_size;
$this->reset();
}
public function reset() {
$this->offset = 0;
$this->finished = false;
}
/**
* Initialize the query by selecting fields and ignoring trashed subscribers.
*
* @return \ORM
*/
protected function select() {
return Subscriber::selectMany(
'first_name',
'last_name',
'email',
'subscribed_ip',
array(
'global_status' => Subscriber::$_table . '.status'
)
)
->filter('filterWithCustomFieldsForExport')
->whereNull(Subscriber::$_table . '.deleted_at');
}
/**
* Filters the subscribers query based on the segments, offset and batch size.
*
* @param \ORM $subscribers
* @return array
*/
abstract protected function filter($subscribers);
/**
* Gets the next batch of subscribers or `false` if no more!
*/
public function get() {
if($this->finished) {
return false;
}
$subscribers = $this->select();
$subscribers = $this->filter($subscribers);
$this->offset += $this->batch_size;
if(count($subscribers) < $this->batch_size) {
$this->finished = true;
}
return $subscribers;
}
}

View File

@ -18,13 +18,15 @@ class ImportExportFactory {
} }
function getSegments($with_confirmed_subscribers = false) { function getSegments($with_confirmed_subscribers = false) {
$segments = ($this->action === self::IMPORT_ACTION) ? if($this->action === self::IMPORT_ACTION) {
Segment::getSegmentsForImport() : $segments = Segment::getSegmentsForImport();
Segment::getSegmentsForExport($with_confirmed_subscribers); } else {
$segments = Hooks::applyFilters('mailpoet_segments_with_subscriber_count', $segments); $segments = Segment::getSegmentsForExport($with_confirmed_subscribers);
$segments = array_values(array_filter($segments, function($segment) { $segments = Hooks::applyFilters('mailpoet_segments_with_subscriber_count', $segments);
return $segment['subscribers'] > 0; $segments = array_values(array_filter($segments, function($segment) {
})); return $segment['subscribers'] > 0;
}));
}
return array_map(function($segment) { return array_map(function($segment) {
if(!$segment['name']) $segment['name'] = __('Not In List', 'mailpoet'); if(!$segment['name']) $segment['name'] = __('Not In List', 'mailpoet');