Rewrite newsletter statistics query, remove redundant queue data from the server response [MAILPOET-746]

This commit is contained in:
Alexey Stoletniy
2016-12-31 13:14:10 +03:00
parent ec9417d293
commit 41fdc3af13
2 changed files with 63 additions and 40 deletions

View File

@ -249,14 +249,23 @@ class Newsletter extends Model {
)->select_expr(MP_NEWSLETTER_OPTION_TABLE.'.value'); )->select_expr(MP_NEWSLETTER_OPTION_TABLE.'.value');
} }
function getQueue() { function getQueue($columns = '*') {
return SendingQueue::where('newsletter_id', $this->id) return SendingQueue::select($columns)
->where('newsletter_id', $this->id)
->orderByDesc('updated_at') ->orderByDesc('updated_at')
->findOne(); ->findOne();
} }
function withSendingQueue() { function withSendingQueue() {
$queue = $this->getQueue(); $queue = $this->getQueue(array(
'id',
'newsletter_id',
'newsletter_rendered_subject',
'status',
'count_processed',
'count_total',
'scheduled_at'
));
if($queue === false) { if($queue === false) {
$this->queue = false; $this->queue = false;
} else { } else {
@ -285,11 +294,7 @@ class Newsletter extends Model {
function withStatistics() { function withStatistics() {
$statistics = $this->getStatistics(); $statistics = $this->getStatistics();
if($statistics === false) { $this->statistics = $statistics;
$this->statistics = false;
} else {
$this->statistics = $statistics->asArray();
}
return $this; return $this;
} }
@ -299,42 +304,42 @@ class Newsletter extends Model {
} }
function getStatistics() { function getStatistics() {
$statistics_query = SendingQueue::tableAlias('queues')
->selectExpr(
'COUNT(DISTINCT(clicks.subscriber_id)) as clicked, ' .
'COUNT(DISTINCT(opens.subscriber_id)) as opened, ' .
'COUNT(DISTINCT(unsubscribes.subscriber_id)) as unsubscribed '
)
->leftOuterJoin(
MP_STATISTICS_CLICKS_TABLE,
'queues.id = clicks.queue_id',
'clicks'
)
->leftOuterJoin(
MP_STATISTICS_OPENS_TABLE,
'queues.id = opens.queue_id',
'opens'
)
->leftOuterJoin(
MP_STATISTICS_UNSUBSCRIBES_TABLE,
'queues.id = unsubscribes.queue_id',
'unsubscribes'
);
if($this->type === self::TYPE_WELCOME) { if($this->type === self::TYPE_WELCOME) {
return $statistics_query $where = '`queue_id` IN (SELECT `id` FROM ' . MP_SENDING_QUEUES_TABLE . '
->where('queues.newsletter_id', $this->id) WHERE `newsletter_id` = ? AND `status` = ?)';
->where('queues.status', SendingQueue::STATUS_COMPLETED) $where_params = array($this->id, SendingQueue::STATUS_COMPLETED);
->findOne();
} else { } else {
if($this->queue === false) { if($this->queue === false) {
return false; return false;
} else { } else {
return $statistics_query $where = '`queue_id` = ?';
->where('queues.id', $this->queue['id']) $where_params = array($this->queue['id']);
->findOne();
} }
} }
$clicks = StatisticsClicks::selectExpr(
'COUNT(DISTINCT subscriber_id) as cnt'
)
->whereRaw($where, $where_params)
->findOne();
$opens = StatisticsOpens::selectExpr(
'COUNT(DISTINCT subscriber_id) as cnt'
)
->whereRaw($where, $where_params)
->findOne();
$unsubscribes = StatisticsUnsubscribes::selectExpr(
'COUNT(DISTINCT subscriber_id) as cnt'
)
->whereRaw($where, $where_params)
->findOne();
return array(
'clicked' => !empty($clicks->cnt) ? $clicks->cnt : 0,
'opened' => !empty($opens->cnt) ? $opens->cnt : 0,
'unsubscribed' => !empty($unsubscribes->cnt) ? $unsubscribes->cnt : 0
);
} }
static function search($orm, $search = '') { static function search($orm, $search = '') {

View File

@ -8,6 +8,8 @@ use MailPoet\Models\NewsletterSegment;
use MailPoet\Models\NewsletterOptionField; use MailPoet\Models\NewsletterOptionField;
use MailPoet\Models\NewsletterOption; use MailPoet\Models\NewsletterOption;
use MailPoet\Models\StatisticsOpens; use MailPoet\Models\StatisticsOpens;
use MailPoet\Models\StatisticsClicks;
use MailPoet\Models\StatisticsUnsubscribes;
class NewsletterTest extends MailPoetTest { class NewsletterTest extends MailPoetTest {
function _before() { function _before() {
@ -135,11 +137,25 @@ class NewsletterTest extends MailPoetTest {
$opens->queue_id = $sending_queue->id; $opens->queue_id = $sending_queue->id;
$opens->save(); $opens->save();
$opens = StatisticsClicks::create();
$opens->subscriber_id = $subscriber->id;
$opens->newsletter_id = $this->newsletter->id;
$opens->queue_id = $sending_queue->id;
$opens->link_id = 0;
$opens->count = 0;
$opens->save();
$opens = StatisticsUnsubscribes::create();
$opens->subscriber_id = $subscriber->id;
$opens->newsletter_id = $this->newsletter->id;
$opens->queue_id = $sending_queue->id;
$opens->save();
$newsletter->queue = $newsletter->getQueue()->asArray(); $newsletter->queue = $newsletter->getQueue()->asArray();
$statistics = $newsletter->getStatistics( $sending_queue->id); $statistics = $newsletter->getStatistics( $sending_queue->id);
expect($statistics->opened)->equals(1); expect($statistics['opened'])->equals(1);
expect($statistics->clicked)->equals(0); expect($statistics['clicked'])->equals(1);
expect($statistics->unsubscribed)->equals(0); expect($statistics['unsubscribed'])->equals(1);
} }
function testItCanCreateOrUpdate() { function testItCanCreateOrUpdate() {
@ -376,5 +392,7 @@ class NewsletterTest extends MailPoetTest {
ORM::raw_execute('TRUNCATE ' . NewsletterSegment::$_table); ORM::raw_execute('TRUNCATE ' . NewsletterSegment::$_table);
ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table); ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table);
ORM::raw_execute('TRUNCATE ' . StatisticsOpens::$_table); ORM::raw_execute('TRUNCATE ' . StatisticsOpens::$_table);
ORM::raw_execute('TRUNCATE ' . StatisticsClicks::$_table);
ORM::raw_execute('TRUNCATE ' . StatisticsUnsubscribes::$_table);
} }
} }