refactored bulk actions & implemented bulk trash for all listings
This commit is contained in:
@ -275,9 +275,13 @@ define(
|
|||||||
} else {
|
} else {
|
||||||
this.props.messages['created']();
|
this.props.messages['created']();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if(response === false) {
|
||||||
|
// unknown error occurred
|
||||||
} else {
|
} else {
|
||||||
this.setState({ errors: response });
|
this.setState({ errors: response });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
handleValueChange: function(e) {
|
handleValueChange: function(e) {
|
||||||
|
@ -241,12 +241,12 @@ define(
|
|||||||
|
|
||||||
var data = params || {};
|
var data = params || {};
|
||||||
|
|
||||||
data.selection = selected_ids;
|
|
||||||
data.listing = {
|
data.listing = {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 0,
|
limit: 0,
|
||||||
group: this.state.group,
|
group: this.state.group,
|
||||||
search: this.state.search
|
search: this.state.search,
|
||||||
|
selection: selected_ids
|
||||||
}
|
}
|
||||||
|
|
||||||
MailPoet.Ajax.post({
|
MailPoet.Ajax.post({
|
||||||
|
@ -27,6 +27,13 @@ define(
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var bulk_actions = [
|
||||||
|
{
|
||||||
|
name: 'trash',
|
||||||
|
label: 'Trash'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
var NewsletterList = React.createClass({
|
var NewsletterList = React.createClass({
|
||||||
renderItem: function(newsletter, actions) {
|
renderItem: function(newsletter, actions) {
|
||||||
var rowClasses = classNames(
|
var rowClasses = classNames(
|
||||||
@ -57,8 +64,8 @@ define(
|
|||||||
<Listing
|
<Listing
|
||||||
endpoint="newsletters"
|
endpoint="newsletters"
|
||||||
onRenderItem={this.renderItem}
|
onRenderItem={this.renderItem}
|
||||||
items={this.getItems}
|
columns={columns}
|
||||||
columns={columns} />
|
bulk_actions={ bulk_actions } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -27,6 +27,13 @@ define(
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var bulk_actions = [
|
||||||
|
{
|
||||||
|
name: 'trash',
|
||||||
|
label: 'Trash'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
var SegmentList = React.createClass({
|
var SegmentList = React.createClass({
|
||||||
renderItem: function(segment, actions) {
|
renderItem: function(segment, actions) {
|
||||||
var rowClasses = classNames(
|
var rowClasses = classNames(
|
||||||
@ -57,8 +64,8 @@ define(
|
|||||||
<Listing
|
<Listing
|
||||||
endpoint="segments"
|
endpoint="segments"
|
||||||
onRenderItem={this.renderItem}
|
onRenderItem={this.renderItem}
|
||||||
items={this.getItems}
|
columns={columns}
|
||||||
columns={columns} />
|
bulk_actions={ bulk_actions } />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -67,7 +67,7 @@ define(
|
|||||||
action: 'listing',
|
action: 'listing',
|
||||||
data: {
|
data: {
|
||||||
'offset': 0,
|
'offset': 0,
|
||||||
'limit': 5,
|
'limit': 100,
|
||||||
'search': '',
|
'search': '',
|
||||||
'sort_by': 'name',
|
'sort_by': 'name',
|
||||||
'sort_order': 'asc'
|
'sort_order': 'asc'
|
||||||
@ -145,7 +145,7 @@ define(
|
|||||||
|
|
||||||
var bulk_actions = [
|
var bulk_actions = [
|
||||||
{
|
{
|
||||||
name: 'move',
|
name: 'moveToList',
|
||||||
label: 'Move to list...',
|
label: 'Move to list...',
|
||||||
onSelect: function() {
|
onSelect: function() {
|
||||||
return (
|
return (
|
||||||
@ -161,7 +161,7 @@ define(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'add',
|
name: 'addToList',
|
||||||
label: 'Add to list...',
|
label: 'Add to list...',
|
||||||
onSelect: function() {
|
onSelect: function() {
|
||||||
return (
|
return (
|
||||||
@ -177,7 +177,7 @@ define(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'remove',
|
name: 'removeFromList',
|
||||||
label: 'Remove from list...',
|
label: 'Remove from list...',
|
||||||
onSelect: function() {
|
onSelect: function() {
|
||||||
return (
|
return (
|
||||||
@ -198,7 +198,7 @@ define(
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
var List = React.createClass({
|
var SubscriberList = React.createClass({
|
||||||
renderItem: function(subscriber, actions) {
|
renderItem: function(subscriber, actions) {
|
||||||
var row_classes = classNames(
|
var row_classes = classNames(
|
||||||
'manage-column',
|
'manage-column',
|
||||||
@ -259,6 +259,6 @@ define(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return List;
|
return SubscriberList;
|
||||||
}
|
}
|
||||||
);
|
);
|
@ -29,6 +29,9 @@ class Initializer {
|
|||||||
\ORM::configure('username', Env::$db_username);
|
\ORM::configure('username', Env::$db_username);
|
||||||
\ORM::configure('password', Env::$db_password);
|
\ORM::configure('password', Env::$db_password);
|
||||||
\ORM::configure('logging', WP_DEBUG);
|
\ORM::configure('logging', WP_DEBUG);
|
||||||
|
\ORM::configure('driver_options', array(
|
||||||
|
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
|
||||||
|
));
|
||||||
|
|
||||||
$subscribers = Env::$db_prefix . 'subscribers';
|
$subscribers = Env::$db_prefix . 'subscribers';
|
||||||
$settings = Env::$db_prefix . 'settings';
|
$settings = Env::$db_prefix . 'settings';
|
||||||
|
28
lib/Listing/BulkAction.php
Normal file
28
lib/Listing/BulkAction.php
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Listing;
|
||||||
|
|
||||||
|
if(!defined('ABSPATH')) exit;
|
||||||
|
|
||||||
|
class BulkAction {
|
||||||
|
private $listing = null;
|
||||||
|
private $data = null;
|
||||||
|
private $model = null;
|
||||||
|
|
||||||
|
function __construct($model, $data) {
|
||||||
|
$this->model = $model;
|
||||||
|
$this->data = $data;
|
||||||
|
|
||||||
|
$this->listing = new Handler(
|
||||||
|
\Model::factory($this->model),
|
||||||
|
$this->data['listing']
|
||||||
|
);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
function apply() {
|
||||||
|
return call_user_func_array(
|
||||||
|
array($this->model, $this->data['action']),
|
||||||
|
array($this->listing, $this->data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -20,7 +20,9 @@ class Handler {
|
|||||||
'sort_by' => (isset($data['sort_by']) ? $data['sort_by'] : 'id'),
|
'sort_by' => (isset($data['sort_by']) ? $data['sort_by'] : 'id'),
|
||||||
'sort_order' => (isset($data['sort_order']) ? $data['sort_order'] : 'asc'),
|
'sort_order' => (isset($data['sort_order']) ? $data['sort_order'] : 'asc'),
|
||||||
// grouping
|
// grouping
|
||||||
'group' => (isset($data['group']) ? $data['group'] : null)
|
'group' => (isset($data['group']) ? $data['group'] : null),
|
||||||
|
// selection
|
||||||
|
'selection' => (isset($data['selection']) ? $data['selection'] : null)
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->setSearch();
|
$this->setSearch();
|
||||||
@ -47,18 +49,18 @@ class Handler {
|
|||||||
return $this->model->filter('group', $this->data['group']);
|
return $this->model->filter('group', $this->data['group']);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelection($ids = array()) {
|
function getSelection() {
|
||||||
if(!empty($ids)) {
|
if(!empty($this->data['selection'])) {
|
||||||
$this->model->whereIn('id', $ids);
|
$this->model->whereIn('id', $this->data['selection']);
|
||||||
}
|
}
|
||||||
return $this->model;
|
return $this->model;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelectionIds($ids = array()) {
|
function getSelectionIds() {
|
||||||
$subscribers = $this->getSelection($ids)->select('id')->findMany();
|
$models = $this->getSelection()->select('id')->findMany();
|
||||||
return array_map(function($subscriber) {
|
return array_map(function($model) {
|
||||||
return (int)$subscriber->id;
|
return (int)$model->id;
|
||||||
}, $subscribers);
|
}, $models);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
|
@ -48,10 +48,18 @@ class Newsletter extends Model {
|
|||||||
|
|
||||||
$saved = $newsletter->save();
|
$saved = $newsletter->save();
|
||||||
|
|
||||||
if($saved === false) {
|
if($saved === true) {
|
||||||
return $newsletter->getValidationErrors();
|
|
||||||
} else {
|
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
$errors = $newsletter->getValidationErrors();
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $errors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function trash($listing) {
|
||||||
|
return $listing->getSelection()->deleteMany();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,10 +57,18 @@ class Segment extends Model {
|
|||||||
|
|
||||||
$saved = $segment->save();
|
$saved = $segment->save();
|
||||||
|
|
||||||
if($saved === false) {
|
if($saved === true) {
|
||||||
return $segment->getValidationErrors();
|
|
||||||
} else {
|
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
$errors = $segment->getValidationErrors();
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $errors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function trash($listing) {
|
||||||
|
return $listing->getSelection()->deleteMany();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,10 +95,76 @@ class Subscriber extends Model {
|
|||||||
|
|
||||||
$saved = $subscriber->save();
|
$saved = $subscriber->save();
|
||||||
|
|
||||||
if($saved === false) {
|
if($saved === true) {
|
||||||
return $subscriber->getValidationErrors();
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
$errors = $subscriber->getValidationErrors();
|
||||||
|
if(!empty($errors)) {
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function moveToList($listing, $data = array()) {
|
||||||
|
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
||||||
|
$segment = Segment::findOne($segment_id);
|
||||||
|
|
||||||
|
if($segment !== false) {
|
||||||
|
$subscribers = $listing->getSelection()->findMany();
|
||||||
|
foreach($subscribers as $subscriber) {
|
||||||
|
// remove subscriber from all segments
|
||||||
|
SubscriberSegment::where('subscriber_id', $subscriber->id)->deleteMany();
|
||||||
|
|
||||||
|
// create relation with segment
|
||||||
|
$association = SubscriberSegment::create();
|
||||||
|
$association->subscriber_id = $subscriber->id;
|
||||||
|
$association->segment_id = $segment->id;
|
||||||
|
$association->save();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function removeFromList($listing, $data = array()) {
|
||||||
|
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
||||||
|
$segment = Segment::findOne($segment_id);
|
||||||
|
|
||||||
|
if($segment !== false) {
|
||||||
|
// delete relations with segment
|
||||||
|
$subscriber_ids = $listing->getSelectionIds();
|
||||||
|
SubscriberSegment::whereIn('subscriber_id', $subscriber_ids)
|
||||||
|
->where('segment_id', $segment->id)
|
||||||
|
->deleteMany();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function addToList($listing, $data = array()) {
|
||||||
|
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
||||||
|
$segment = Segment::findOne($segment_id);
|
||||||
|
|
||||||
|
if($segment !== false) {
|
||||||
|
$subscribers = $listing->getSelection()->findMany();
|
||||||
|
foreach($subscribers as $subscriber) {
|
||||||
|
// create relation with segment
|
||||||
|
$association = \MailPoet\Models\SubscriberSegment::create();
|
||||||
|
$association->subscriber_id = $subscriber->id;
|
||||||
|
$association->segment_id = $segment->id;
|
||||||
|
$association->save();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function trash($listing) {
|
||||||
|
// delete relations with all segments
|
||||||
|
$subscriber_ids = $listing->getSelectionIds();
|
||||||
|
\MailPoet\Models\SubscriberSegment::whereIn('subscriber_id', $subscriber_ids)->deleteMany();
|
||||||
|
|
||||||
|
return $listing->getSelection()->deleteMany();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,4 +62,13 @@ class Newsletters {
|
|||||||
$mailer = new Bridge($newsletter, $subscribers);
|
$mailer = new Bridge($newsletter, $subscribers);
|
||||||
wp_send_json($mailer->send());
|
wp_send_json($mailer->send());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bulk_action($data = array()) {
|
||||||
|
$bulk_action = new Listing\BulkAction(
|
||||||
|
'\MailPoet\Models\Newsletter',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_send_json($bulk_action->apply());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ class Router {
|
|||||||
$class = ucfirst($_POST['endpoint']);
|
$class = ucfirst($_POST['endpoint']);
|
||||||
$endpoint = __NAMESPACE__ . "\\" . $class;
|
$endpoint = __NAMESPACE__ . "\\" . $class;
|
||||||
$method = $_POST['method'];
|
$method = $_POST['method'];
|
||||||
$data = isset($_POST['data']) ? $_POST['data'] : array();
|
$data = isset($_POST['data']) ? stripslashes_deep($_POST['data']) : array();
|
||||||
$endpoint = new $endpoint();
|
$endpoint = new $endpoint();
|
||||||
$endpoint->$method($data);
|
$endpoint->$method($data);
|
||||||
}
|
}
|
||||||
|
@ -53,4 +53,13 @@ class Segments {
|
|||||||
|
|
||||||
wp_send_json($result);
|
wp_send_json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bulk_action($data = array()) {
|
||||||
|
$bulk_action = new Listing\BulkAction(
|
||||||
|
'\MailPoet\Models\Segment',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_send_json($bulk_action->apply());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,69 +30,6 @@ class Subscribers {
|
|||||||
wp_send_json($listing->get());
|
wp_send_json($listing->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
function bulk_action($data = array()) {
|
|
||||||
$action = $data['action'];
|
|
||||||
$selection = (isset($data['selection']) ? $data['selection'] : null);
|
|
||||||
$listing_data = $data['listing'];
|
|
||||||
|
|
||||||
$listing = new Listing\Handler(
|
|
||||||
\Model::factory('\MailPoet\Models\Subscriber'),
|
|
||||||
$listing_data
|
|
||||||
);
|
|
||||||
|
|
||||||
$selected = $listing->getSelection($selection);
|
|
||||||
$subscribers = $selected->findMany();
|
|
||||||
|
|
||||||
$result = false;
|
|
||||||
switch($action) {
|
|
||||||
case 'move':
|
|
||||||
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
|
||||||
foreach($subscribers as $subscriber) {
|
|
||||||
// remove subscriber from all segments
|
|
||||||
SubscriberSegment::where('subscriber_id', $subscriber->id)->deleteMany();
|
|
||||||
|
|
||||||
// create relation with segment
|
|
||||||
$association = SubscriberSegment::create();
|
|
||||||
$association->subscriber_id = $subscriber->id;
|
|
||||||
$association->segment_id = $segment_id;
|
|
||||||
$association->save();
|
|
||||||
}
|
|
||||||
$result = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'remove':
|
|
||||||
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
|
||||||
// delete relations with segment
|
|
||||||
$subscriber_ids = $listing->getSelectionIds($selection);
|
|
||||||
$result = SubscriberSegment::whereIn('subscriber_id', $subscriber_ids)
|
|
||||||
->where('segment_id', $segment_id)
|
|
||||||
->deleteMany();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'add':
|
|
||||||
$segment_id = (isset($data['segment_id']) ? (int)$data['segment_id'] : 0);
|
|
||||||
foreach($subscribers as $subscriber) {
|
|
||||||
// create relation with segment
|
|
||||||
$association = SubscriberSegment::create();
|
|
||||||
$association->subscriber_id = $subscriber->id;
|
|
||||||
$association->segment_id = $segment_id;
|
|
||||||
$association->save();
|
|
||||||
}
|
|
||||||
$result = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'trash':
|
|
||||||
// delete relations with all segments
|
|
||||||
$subscriber_ids = $listing->getSelectionIds($selection);
|
|
||||||
SubscriberSegment::whereIn('subscriber_id', $subscriber_ids)->deleteMany();
|
|
||||||
|
|
||||||
$result = $selected->deleteMany();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
wp_send_json($result);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAll() {
|
function getAll() {
|
||||||
$collection = Subscriber::findArray();
|
$collection = Subscriber::findArray();
|
||||||
wp_send_json($collection);
|
wp_send_json($collection);
|
||||||
@ -112,4 +49,13 @@ class Subscribers {
|
|||||||
}
|
}
|
||||||
wp_send_json($result);
|
wp_send_json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bulk_action($data = array()) {
|
||||||
|
$bulk_action = new Listing\BulkAction(
|
||||||
|
'\MailPoet\Models\Subscriber',
|
||||||
|
$data
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_send_json($bulk_action->apply());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,8 +122,9 @@ abstract class ValidModel extends \Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
$errs = $this->getValidationErrors();
|
$errs = $this->getValidationErrors();
|
||||||
if (!empty($errs))
|
if (!empty($errs)) {
|
||||||
$this->doValidationError(self::ON_SAVE);
|
$this->doValidationError(self::ON_SAVE);
|
||||||
|
}
|
||||||
|
|
||||||
parent::save();
|
parent::save();
|
||||||
}
|
}
|
||||||
@ -148,9 +149,10 @@ abstract class ValidModel extends \Model
|
|||||||
// Protected methods
|
// Protected methods
|
||||||
protected function doValidationError($context)
|
protected function doValidationError($context)
|
||||||
{
|
{
|
||||||
if ($context == $this->_validationOptions['throw'])
|
if ($context == $this->_validationOptions['throw']) {
|
||||||
throw new \Sudzy\ValidationException($this->_validationErrors);
|
throw new \Sudzy\ValidationException($this->_validationErrors);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected function addValidationError($msg, $field = null)
|
protected function addValidationError($msg, $field = null)
|
||||||
{
|
{
|
||||||
@ -177,4 +179,4 @@ abstract class ValidModel extends \Model
|
|||||||
{
|
{
|
||||||
if (null == $this->_validator) $this->_validator = new \Sudzy\Engine(); // Is lazy setup worth it?
|
if (null == $this->_validator) $this->_validator = new \Sudzy\Engine(); // Is lazy setup worth it?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user