refactored bulk actions & implemented bulk trash for all listings

This commit is contained in:
Jonathan Labreuille
2015-09-18 17:39:25 +02:00
parent cbcd614b6f
commit 239e2583d2
16 changed files with 259 additions and 160 deletions

View File

@ -275,9 +275,13 @@ define(
} else {
this.props.messages['created']();
}
} else {
if(response === false) {
// unknown error occurred
} else {
this.setState({ errors: response });
}
}
}.bind(this));
},
handleValueChange: function(e) {

View File

@ -241,12 +241,12 @@ define(
var data = params || {};
data.selection = selected_ids;
data.listing = {
offset: 0,
limit: 0,
group: this.state.group,
search: this.state.search
search: this.state.search,
selection: selected_ids
}
MailPoet.Ajax.post({

View File

@ -27,6 +27,13 @@ define(
}
];
var bulk_actions = [
{
name: 'trash',
label: 'Trash'
}
];
var NewsletterList = React.createClass({
renderItem: function(newsletter, actions) {
var rowClasses = classNames(
@ -57,8 +64,8 @@ define(
<Listing
endpoint="newsletters"
onRenderItem={this.renderItem}
items={this.getItems}
columns={columns} />
columns={columns}
bulk_actions={ bulk_actions } />
);
}
});

View File

@ -27,6 +27,13 @@ define(
}
];
var bulk_actions = [
{
name: 'trash',
label: 'Trash'
}
];
var SegmentList = React.createClass({
renderItem: function(segment, actions) {
var rowClasses = classNames(
@ -57,8 +64,8 @@ define(
<Listing
endpoint="segments"
onRenderItem={this.renderItem}
items={this.getItems}
columns={columns} />
columns={columns}
bulk_actions={ bulk_actions } />
);
}
});

View File

@ -67,7 +67,7 @@ define(
action: 'listing',
data: {
'offset': 0,
'limit': 5,
'limit': 100,
'search': '',
'sort_by': 'name',
'sort_order': 'asc'
@ -145,7 +145,7 @@ define(
var bulk_actions = [
{
name: 'move',
name: 'moveToList',
label: 'Move to list...',
onSelect: function() {
return (
@ -161,7 +161,7 @@ define(
}
},
{
name: 'add',
name: 'addToList',
label: 'Add to list...',
onSelect: function() {
return (
@ -177,7 +177,7 @@ define(
}
},
{
name: 'remove',
name: 'removeFromList',
label: 'Remove from list...',
onSelect: function() {
return (
@ -198,7 +198,7 @@ define(
}
];
var List = React.createClass({
var SubscriberList = React.createClass({
renderItem: function(subscriber, actions) {
var row_classes = classNames(
'manage-column',
@ -259,6 +259,6 @@ define(
}
});
return List;
return SubscriberList;
}
);

View File

@ -29,6 +29,9 @@ class Initializer {
\ORM::configure('username', Env::$db_username);
\ORM::configure('password', Env::$db_password);
\ORM::configure('logging', WP_DEBUG);
\ORM::configure('driver_options', array(
\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
));
$subscribers = Env::$db_prefix . 'subscribers';
$settings = Env::$db_prefix . 'settings';

View 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)
);
}
}

View File

@ -20,7 +20,9 @@ class Handler {
'sort_by' => (isset($data['sort_by']) ? $data['sort_by'] : 'id'),
'sort_order' => (isset($data['sort_order']) ? $data['sort_order'] : 'asc'),
// 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();
@ -47,18 +49,18 @@ class Handler {
return $this->model->filter('group', $this->data['group']);
}
function getSelection($ids = array()) {
if(!empty($ids)) {
$this->model->whereIn('id', $ids);
function getSelection() {
if(!empty($this->data['selection'])) {
$this->model->whereIn('id', $this->data['selection']);
}
return $this->model;
}
function getSelectionIds($ids = array()) {
$subscribers = $this->getSelection($ids)->select('id')->findMany();
return array_map(function($subscriber) {
return (int)$subscriber->id;
}, $subscribers);
function getSelectionIds() {
$models = $this->getSelection()->select('id')->findMany();
return array_map(function($model) {
return (int)$model->id;
}, $models);
}
function get() {

View File

@ -48,10 +48,18 @@ class Newsletter extends Model {
$saved = $newsletter->save();
if($saved === false) {
return $newsletter->getValidationErrors();
} else {
if($saved === true) {
return true;
} else {
$errors = $newsletter->getValidationErrors();
if(!empty($errors)) {
return $errors;
}
}
return false;
}
static function trash($listing) {
return $listing->getSelection()->deleteMany();
}
}

View File

@ -57,10 +57,18 @@ class Segment extends Model {
$saved = $segment->save();
if($saved === false) {
return $segment->getValidationErrors();
} else {
if($saved === true) {
return true;
} else {
$errors = $segment->getValidationErrors();
if(!empty($errors)) {
return $errors;
}
}
return false;
}
static function trash($listing) {
return $listing->getSelection()->deleteMany();
}
}

View File

@ -95,10 +95,76 @@ class Subscriber extends Model {
$saved = $subscriber->save();
if($saved === false) {
return $subscriber->getValidationErrors();
if($saved === true) {
return true;
} 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 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();
}
}

View File

@ -62,4 +62,13 @@ class Newsletters {
$mailer = new Bridge($newsletter, $subscribers);
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());
}
}

View File

@ -24,7 +24,7 @@ class Router {
$class = ucfirst($_POST['endpoint']);
$endpoint = __NAMESPACE__ . "\\" . $class;
$method = $_POST['method'];
$data = isset($_POST['data']) ? $_POST['data'] : array();
$data = isset($_POST['data']) ? stripslashes_deep($_POST['data']) : array();
$endpoint = new $endpoint();
$endpoint->$method($data);
}

View File

@ -53,4 +53,13 @@ class Segments {
wp_send_json($result);
}
function bulk_action($data = array()) {
$bulk_action = new Listing\BulkAction(
'\MailPoet\Models\Segment',
$data
);
wp_send_json($bulk_action->apply());
}
}

View File

@ -30,69 +30,6 @@ class Subscribers {
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() {
$collection = Subscriber::findArray();
wp_send_json($collection);
@ -112,4 +49,13 @@ class Subscribers {
}
wp_send_json($result);
}
function bulk_action($data = array()) {
$bulk_action = new Listing\BulkAction(
'\MailPoet\Models\Subscriber',
$data
);
wp_send_json($bulk_action->apply());
}
}

View File

@ -122,8 +122,9 @@ abstract class ValidModel extends \Model
}
$errs = $this->getValidationErrors();
if (!empty($errs))
if (!empty($errs)) {
$this->doValidationError(self::ON_SAVE);
}
parent::save();
}
@ -148,9 +149,10 @@ abstract class ValidModel extends \Model
// Protected methods
protected function doValidationError($context)
{
if ($context == $this->_validationOptions['throw'])
if ($context == $this->_validationOptions['throw']) {
throw new \Sudzy\ValidationException($this->_validationErrors);
}
}
protected function addValidationError($msg, $field = null)
{