Newsletter Segment relation

- added newsletter_segment table
- added NewsletterSegment model
- added list filter on newsletters listing
- unit tests
This commit is contained in:
Jonathan Labreuille
2015-10-06 11:13:38 +02:00
parent c15359f1b4
commit ecb522955b
9 changed files with 178 additions and 18 deletions

View File

@@ -39,6 +39,7 @@ class Initializer {
$newsletter_templates = Env::$db_prefix . 'newsletter_templates';
$segments = Env::$db_prefix . 'segments';
$subscriber_segment = Env::$db_prefix . 'subscriber_segment';
$newsletter_segment = Env::$db_prefix . 'newsletter_segment';
define('MP_SUBSCRIBERS_TABLE', $subscribers);
define('MP_SETTINGS_TABLE', $settings);
@@ -46,6 +47,7 @@ class Initializer {
define('MP_SEGMENTS_TABLE', $segments);
define('MP_SUBSCRIBER_SEGMENT_TABLE', $subscriber_segment);
define('MP_NEWSLETTER_TEMPLATES_TABLE', $newsletter_templates);
define('MP_NEWSLETTER_SEGMENT_TABLE', $newsletter_segment);
}
function setupActivator() {

View File

@@ -15,7 +15,8 @@ class Migrator {
'newsletters',
'newsletter_templates',
'segments',
'subscriber_segment'
'subscriber_segment',
'newsletter_segment'
);
}
@@ -120,6 +121,18 @@ class Migrator {
return $this->sqlify(__FUNCTION__, $attributes);
}
function newsletter_segment() {
$attributes = array(
'id mediumint(9) NOT NULL AUTO_INCREMENT,',
'newsletter_id mediumint(9) NOT NULL,',
'segment_id mediumint(9) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id)'
);
return $this->sqlify(__FUNCTION__, $attributes);
}
private function sqlify($model, $attributes) {
$table = $this->prefix . $model;

View File

@@ -27,9 +27,9 @@ class Handler {
'selection' => (isset($data['selection']) ? $data['selection'] : null)
);
$this->setFilter();
$this->setSearch();
$this->setGroup();
$this->setFilter();
$this->setOrder();
}

View File

@@ -10,10 +10,72 @@ class Newsletter extends Model {
parent::__construct();
}
function segments() {
return $this->has_many_through(
__NAMESPACE__.'\Segment',
__NAMESPACE__.'\NewsletterSegment',
'newsletter_id',
'segment_id'
);
}
static function search($orm, $search = '') {
return $orm->where_like('subject', '%' . $search . '%');
}
static function filters() {
$segments = Segment::orderByAsc('name')->findMany();
$segment_list = array();
$segment_list[] = array(
'label' => __('All lists'),
'value' => ''
);
foreach($segments as $segment) {
$newsletters_count = $segment->newsletters()->count();
if($newsletters_count > 0) {
$segment_list[] = array(
'label' => sprintf('%s (%d)', $segment->name, $newsletters_count),
'value' => $segment->id()
);
}
}
$filters = array(
array(
'name' => 'segment',
'options' => $segment_list
)
);
return $filters;
}
static function filterBy($orm, $filters = null) {
if(empty($filters)) {
return $orm;
}
foreach($filters as $filter) {
if($filter['name'] === 'segment') {
$segment = Segment::findOne($filter['value']);
if($segment !== false) {
$orm = $orm
->select('model.*')
->select('newsletter_segment.id', 'newsletter_segment_id')
->join(
MP_NEWSLETTER_SEGMENT_TABLE,
'model.id = newsletter_segment.newsletter_id',
'newsletter_segment'
)
->where('newsletter_segment.segment_id', (int)$filter['value']);
}
}
}
return $orm;
}
static function groups() {
return array(
array(

View File

@@ -0,0 +1,12 @@
<?php
namespace MailPoet\Models;
if(!defined('ABSPATH')) exit;
class NewsletterSegment extends Model {
public static $_table = MP_NEWSLETTER_SEGMENT_TABLE;
function __construct() {
parent::__construct();
}
}

View File

@@ -23,6 +23,15 @@ class Segment extends Model {
);
}
function newsletters() {
return $this->has_many_through(
__NAMESPACE__.'\Newsletter',
__NAMESPACE__.'\NewsletterSegment',
'segment_id',
'newsletter_id'
);
}
static function search($orm, $search = '') {
return $orm->where_like('name', '%'.$search.'%');
}

View File

@@ -69,13 +69,21 @@ class Subscriber extends Model {
foreach($filters as $filter) {
if($filter['name'] === 'segment') {
$segment = Segment::findOne($filter['value']);
if($segment !== false) {
$orm = $segment->subscribers();
$orm = $orm
->select('model.*')
->select('subscriber_segment.id', 'subscriber_segment_id')
->join(
MP_SUBSCRIBER_SEGMENT_TABLE,
'model.id = subscriber_segment.subscriber_id',
'subscriber_segment'
)
->where('subscriber_segment.segment_id', (int)$filter['value']);
}
}
}
return $orm;
}

View File

@@ -1,6 +1,8 @@
<?php
use MailPoet\Models\Newsletter;
use MailPoet\Models\Segment;
use MailPoet\Models\NewsletterSegment;
class NewsletterCest {
function _before() {
@@ -9,7 +11,7 @@ class NewsletterCest {
'subject' => 'new newsletter',
'body' => 'body',
'type' => 'standard',
'preheader' => 'preaheader'
'preheader' => 'preheader'
);
$newsletter = Newsletter::create();
@@ -22,27 +24,50 @@ class NewsletterCest {
}
function itHasSubject() {
$subscriber = Newsletter::where('subject', $this->data['subject'])
$newsletter = Newsletter::where('subject', $this->data['subject'])
->findOne();
expect($subscriber->subject)->equals($this->data['subject']);
expect($newsletter->subject)->equals($this->data['subject']);
}
function itHasType() {
$subscriber = Newsletter::where('type', $this->data['type'])
$newsletter = Newsletter::where('type', $this->data['type'])
->findOne();
expect($subscriber->type)->equals($this->data['type']);
expect($newsletter->type)->equals($this->data['type']);
}
function itHasBody() {
$subscriber = Newsletter::where('body', $this->data['body'])
$newsletter = Newsletter::where('body', $this->data['body'])
->findOne();
expect($subscriber->body)->equals($this->data['body']);
expect($newsletter->body)->equals($this->data['body']);
}
function itHasPreheader() {
$subscriber = Newsletter::where('preheader', $this->data['preheader'])
$newsletter = Newsletter::where('preheader', $this->data['preheader'])
->findOne();
expect($subscriber->preheader)->equals($this->data['preheader']);
expect($newsletter->preheader)->equals($this->data['preheader']);
}
function itCanHaveASegment() {
$segmentData = array(
'name' => 'my first list'
);
$segment = Segment::create();
$segment->hydrate($segmentData);
$segment->save();
$newsletter = Newsletter::create();
$newsletter->hydrate($this->data);
$newsletter->save();
$association = NewsletterSegment::create();
$association->newsletter_id = $newsletter->id();
$association->segment_id = $segment->id();
$association->save();
$newsletter = Newsletter::findOne($newsletter->id);
$newsletterSegment = $newsletter->segments()->findOne();
expect($newsletterSegment->id)->equals($segment->id);
}
function itCanCreateOrUpdate() {

View File

@@ -3,6 +3,8 @@
use MailPoet\Models\SubscriberSegment;
use MailPoet\Models\Subscriber;
use MailPoet\Models\Segment;
use MailPoet\Models\Newsletter;
use MailPoet\Models\NewsletterSegment;
class SegmentCest {
function _before() {
@@ -78,7 +80,7 @@ class SegmentCest {
expect($segment->name)->equals('updated list');
}
function itCanHaveMultipleSubscribers() {
function itCanHaveManySubscribers() {
$subscribersData = array(
array(
'first_name' => 'John',
@@ -91,7 +93,8 @@ class SegmentCest {
'email' => 'mike@maipoet.com'
)
);
foreach ($subscribersData as $subscriberData) {
foreach($subscribersData as $subscriberData) {
$subscriber = Subscriber::create();
$subscriber->hydrate($subscriberData);
$subscriber->save();
@@ -101,12 +104,38 @@ class SegmentCest {
$association->save();
}
$segment = Segment::find_one($this->segment->id);
$subscribers = $segment->subscribers()
->find_array();
$segment = Segment::findOne($this->segment->id);
$subscribers = $segment->subscribers()->findArray();
expect(count($subscribers))->equals(2);
}
function itCanHaveManyNewsletters() {
$newslettersData = array(
array(
'subject' => 'My first newsletter'
),
array(
'subject' => 'My second newsletter'
)
);
foreach($newslettersData as $newsletterData) {
$newsletter = Newsletter::create();
$newsletter->hydrate($newsletterData);
$newsletter->save();
$association = NewsletterSegment::create();
$association->newsletter_id = $newsletter->id;
$association->segment_id = $this->segment->id;
$association->save();
}
$segment = Segment::findOne($this->segment->id);
$newsletters = $segment->newsletters()->findArray();
expect(count($newsletters))->equals(2);
}
function _after() {
ORM::forTable(Segment::$_table)
->deleteMany();