diff --git a/assets/js/src/subscribers/list.jsx b/assets/js/src/subscribers/list.jsx
index 2c2a1dfbd3..9993b4fd0c 100644
--- a/assets/js/src/subscribers/list.jsx
+++ b/assets/js/src/subscribers/list.jsx
@@ -313,6 +313,7 @@ const SubscriberList = React.createClass({
'SET NAMES utf8',
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET TIME_ZONE = "+00:00"'
diff --git a/lib/Config/Menu.php b/lib/Config/Menu.php
index 79c6c1c0d5..642fdc20c4 100644
--- a/lib/Config/Menu.php
+++ b/lib/Config/Menu.php
@@ -67,7 +67,7 @@ class Menu {
'forms'
)
);
- add_submenu_page(
+ $hook_subscribers_page = add_submenu_page(
'mailpoet',
__('Subscribers'),
__('Subscribers'),
@@ -182,6 +182,17 @@ class Menu {
'cron'
)
);
+
+ add_action('load-'.$hook_subscribers_page, function() {
+ add_screen_option('per_page', array(
+ 'label' => _x(
+ 'Number of subscribers per page',
+ 'subscribers per page (screen options)'
+ ),
+ 'default' => 10,
+ 'option' => 'mailpoet_subscribers_per_page'
+ ));
+ });
}
function home() {
@@ -305,6 +316,13 @@ class Menu {
function subscribers() {
$data = array();
+ // listing: limit per page
+ $data['per_page'] = get_user_meta(
+ get_current_user_id(),
+ 'mailpoet_subscribers_per_page',
+ true
+ );
+
$data['segments'] = Segment::findArray();
$data['custom_fields'] = array_map(function($field) {
diff --git a/lib/Models/Model.php b/lib/Models/Model.php
index a18f14f273..4116532158 100644
--- a/lib/Models/Model.php
+++ b/lib/Models/Model.php
@@ -5,6 +5,7 @@ if(!defined('ABSPATH')) exit;
class Model extends \Sudzy\ValidModel {
protected $_errors;
+ const BULK_ACTION_BATCH_SIZE = 1000;
function __construct() {
$this->_errors = array();
@@ -70,19 +71,23 @@ class Model extends \Sudzy\ValidModel {
}
static function bulkTrash($orm) {
- $models = $orm->findResultSet();
- $models->set_expr('deleted_at', 'NOW()')->save();
- return $models->count();
+ $model = get_called_class();
+ return self::bulkAction($orm, function($ids) use($model) {
+ self::rawExecute(join(' ', array(
+ 'UPDATE `'.$model::$_table.'`',
+ 'SET `deleted_at`=NOW()',
+ 'WHERE `id` IN ('.rtrim(str_repeat('?,', count($ids)), ',').')'
+ )),
+ $ids
+ );
+ });
}
static function bulkDelete($orm) {
- $models = $orm->findMany();
- $count = 0;
- foreach($models as $model) {
- $model->delete();
- $count++;
- }
- return $count;
+ $model = get_called_class();
+ return self::bulkAction($orm, function($ids) use($model) {
+ $model::whereIn('id', $ids)->deleteMany();
+ });
}
function restore() {
@@ -90,9 +95,35 @@ class Model extends \Sudzy\ValidModel {
}
static function bulkRestore($orm) {
- $models = $orm->findResultSet();
- $models->set_expr('deleted_at', 'NULL')->save();
- return $models->count();
+ $model = get_called_class();
+ return self::bulkAction($orm, function($ids) use($model) {
+ self::rawExecute(join(' ', array(
+ 'UPDATE `'.$model::$_table.'`',
+ 'SET `deleted_at`=NULL',
+ 'WHERE `id` IN ('.rtrim(str_repeat('?,', count($ids)), ',').')'
+ )),
+ $ids
+ );
+ });
+ }
+
+ static function bulkAction($orm, $callback = false) {
+ $total = $orm->count();
+
+ $models = $orm->select('id')
+ ->offset(null)
+ ->limit(null)
+ ->findArray();
+
+ $ids = array_map(function($model) {
+ return (int)$model['id'];
+ }, $models);
+
+ if(is_callable($callback)) {
+ $callback($ids);
+ }
+
+ return $total;
}
function duplicate($data = array()) {
diff --git a/lib/Models/Subscriber.php b/lib/Models/Subscriber.php
index 722b0d3a24..cc70fd4199 100644
--- a/lib/Models/Subscriber.php
+++ b/lib/Models/Subscriber.php
@@ -411,7 +411,6 @@ class Subscriber extends Model {
}
static function bulkAddToList($orm, $data = array()) {
-
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
$segment = Segment::findOne($segment_id);
@@ -435,6 +434,15 @@ class Subscriber extends Model {
return false;
}
+ static function bulkDelete($orm) {
+ return parent::bulkAction($orm, function($ids) {
+ // delete subscribers
+ Subscriber::whereIn('id', $ids)->deleteMany();
+ // delete subscribers' relations to segments
+ SubscriberSegment::whereIn('subscriber_id', $ids)->deleteMany();
+ });
+ }
+
static function subscribed($orm) {
return $orm
->whereNull('deleted_at')
diff --git a/views/forms.html b/views/forms.html
index 9cf6f2b4f2..840fa75ba0 100644
--- a/views/forms.html
+++ b/views/forms.html
@@ -8,12 +8,15 @@
'searchLabel': __('Search'),
'loadingItems': __('Loading forms...'),
'noItemsFound': __('No forms found.'),
+ 'selectAllLabel': __('All forms on this page are selected.'),
+ 'selectedAllLabel': __('All %d forms are selected.'),
+ 'selectAllLink': __('Select all forms on all pages.'),
+ 'clearSelection': __('Clear selection.'),
'permanentlyDeleted': __('%d forms permanently deleted.')
}) %>
diff --git a/views/newsletters.html b/views/newsletters.html
index 7959edc042..65cae54eec 100644
--- a/views/newsletters.html
+++ b/views/newsletters.html
@@ -10,7 +10,7 @@
'noItemsFound': __('No newsletters found.'),
'selectAllLabel': __('All newsletters on this page are selected.'),
'selectedAllLabel': __('All %d newsletters are selected.'),
- 'selectAllLink': __('Select all pages.'),
+ 'selectAllLink': __('Select all newsletters on all pages.'),
'clearSelection': __('Clear selection.'),
'permanentlyDeleted': __('%d newsletters permanently deleted.')
}) %>
diff --git a/views/subscribers/subscribers.html b/views/subscribers/subscribers.html
index f2ccbc72be..143ddbf2ad 100644
--- a/views/subscribers/subscribers.html
+++ b/views/subscribers/subscribers.html
@@ -10,12 +10,13 @@
'noItemsFound': __('No subscribers found.'),
'selectAllLabel': __('All subscribers on this page are selected.'),
'selectedAllLabel': __('All %d subscribers are selected.'),
- 'selectAllLink': __('Select all pages.'),
+ 'selectAllLink': __('Select all subscribers on all pages.'),
'clearSelection': __('Clear selection.'),
'permanentlyDeleted': __('%d subscribers permanently deleted.')
}) %>