Merge pull request #1353 from mailpoet/subscriber-source

Subscriber source [MAILPOET-1377]
This commit is contained in:
Michelle Shull
2018-05-14 10:19:00 -04:00
committed by GitHub
11 changed files with 119 additions and 6 deletions

View File

@@ -14,6 +14,7 @@ use MailPoet\Models\Subscriber;
use MailPoet\Newsletter\Scheduler\Scheduler;
use MailPoet\Segments\BulkAction;
use MailPoet\Segments\SubscribersListings;
use MailPoet\Subscribers\Source;
use MailPoet\Subscription\Throttling as SubscriptionThrottling;
use MailPoet\WP\Hooks;
@@ -191,6 +192,11 @@ class Subscribers extends APIEndpoint {
return $this->badRequest($errors);
}
if($subscriber->isNew()) {
$subscriber = Source::setSource($subscriber, Source::ADMINISTRATOR);
$subscriber->save();
}
if(!empty($data['segments'])) {
Scheduler::scheduleSubscriberWelcomeNotification($subscriber->id, $data['segments']);
}

View File

@@ -6,6 +6,7 @@ use MailPoet\Models\Segment;
use MailPoet\Models\Subscriber;
use MailPoet\Models\SubscriberSegment;
use MailPoet\Newsletter\Scheduler\Scheduler;
use MailPoet\Subscribers\Source;
if(!defined('ABSPATH')) exit;
@@ -165,6 +166,7 @@ class API {
// add subscriber
$new_subscriber = Subscriber::create();
$new_subscriber->hydrate($default_fields);
$new_subscriber = Source::setSource($new_subscriber, Source::API);
$new_subscriber->save();
if($new_subscriber->getErrors() !== false) {
throw new \Exception(

View File

@@ -171,6 +171,7 @@ class Migrator {
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'deleted_at TIMESTAMP NULL,',
'unconfirmed_data longtext,',
'source ENUM("form", "imported", "administrator", "api", "wordpress_user", "unknown") DEFAULT "unknown",',
'PRIMARY KEY (id),',
'UNIQUE KEY email (email),',
'KEY wp_user_id (wp_user_id),',

View File

@@ -2,6 +2,7 @@
namespace MailPoet\Models;
use MailPoet\Mailer\Mailer;
use MailPoet\Newsletter\Scheduler\Scheduler;
use MailPoet\Subscribers\Source;
use MailPoet\Util\Helpers;
use MailPoet\Subscription;
@@ -182,6 +183,8 @@ class Subscriber extends Model {
// create new subscriber or update if no confirmation is required
$subscriber = self::createOrUpdate($subscriber_data);
if($subscriber->getErrors() !== false) {
$subscriber = Source::setSource($subscriber, Source::FORM);
$subscriber->save();
return $subscriber;
}
@@ -206,6 +209,8 @@ class Subscriber extends Model {
}
}
$subscriber = Source::setSource($subscriber, Source::FORM);
if($subscriber->save()) {
// link subscriber to segments
SubscriberSegment::subscribeToSegments($subscriber, $segment_ids);

View File

@@ -6,6 +6,7 @@ use MailPoet\Models\Subscriber;
use MailPoet\Models\Segment;
use MailPoet\Models\SubscriberSegment;
use MailPoet\Newsletter\Scheduler\Scheduler;
use MailPoet\Subscribers\Source;
if(!defined('ABSPATH')) exit;
@@ -50,12 +51,14 @@ class WP {
'first_name' => $first_name,
'last_name' => $last_name,
'status' => Subscriber::STATUS_SUBSCRIBED,
'source' => Source::WORDPRESS_USER,
);
if($subscriber !== false) {
$data['id'] = $subscriber->id();
$data['deleted_at'] = null; // remove the user from the trash
unset($data['status']); // don't override status for existing users
unset($data['source']); // don't override status for existing users
}
$subscriber = Subscriber::createOrUpdate($data);
@@ -137,12 +140,12 @@ class WP {
', $subscribers_table, $wpdb->users))->findArray();
Subscriber::raw_execute(sprintf('
INSERT IGNORE INTO %1$s(wp_user_id, email, status, created_at)
SELECT wu.id, wu.user_email, "subscribed", CURRENT_TIMESTAMP() FROM %2$s wu
INSERT IGNORE INTO %1$s(wp_user_id, email, status, created_at, source)
SELECT wu.id, wu.user_email, "subscribed", CURRENT_TIMESTAMP(), "%3$s" FROM %2$s wu
LEFT JOIN %1$s mps ON wu.id = mps.wp_user_id
WHERE mps.wp_user_id IS NULL AND wu.user_email != ""
ON DUPLICATE KEY UPDATE wp_user_id = wu.id
', $subscribers_table, $wpdb->users));
', $subscribers_table, $wpdb->users, Source::WORDPRESS_USER));
return $inserterd_user_ids;
}

View File

@@ -9,6 +9,7 @@ use MailPoet\Models\Subscriber;
use MailPoet\Models\SubscriberCustomField;
use MailPoet\Models\SubscriberSegment;
use MailPoet\Subscribers\ImportExport\ImportExportFactory;
use MailPoet\Subscribers\Source;
use MailPoet\Util\Helpers;
class Import {
@@ -108,6 +109,7 @@ class Import {
// add, if required, missing required fields to new subscribers
$new_subscribers = $this->addMissingRequiredFields($new_subscribers);
$new_subscribers = $this->setSubscriptionStatusToSubscribed($new_subscribers);
$new_subscribers = $this->setSource($new_subscribers);
$created_subscribers =
$this->createOrUpdateSubscribers(
'create',
@@ -286,6 +288,17 @@ class Import {
return $subscribers_data;
}
function setSource($subscribers_data) {
$subscribers_count = count($subscribers_data['data'][key($subscribers_data['data'])]);
$subscribers_data['fields'][] = 'source';
$subscribers_data['data']['source'] = array_fill(
0,
$subscribers_count,
Source::IMPORTED
);
return $subscribers_data;
}
function getSubscribersFields($subscribers_fields) {
return array_values(
array_filter(

View File

@@ -0,0 +1,37 @@
<?php
namespace MailPoet\Subscribers;
use MailPoet\Models\Subscriber;
class Source {
const FORM = 'form';
const IMPORTED = 'imported';
const ADMINISTRATOR = 'administrator';
const API = 'api';
const WORDPRESS_USER = 'wordpress_user';
const UNKNOWN = 'unknown';
private static $allowed_sources = array(
Source::FORM,
Source::IMPORTED,
Source::ADMINISTRATOR,
Source::API,
Source::WORDPRESS_USER,
Source::UNKNOWN,
);
static function setSource(Subscriber $subscriber, $source) {
if((isset($subscriber->source)) && ($subscriber->source !== Source::UNKNOWN)) {
// we don't want to override source
return $subscriber;
}
if(!in_array($source, Source::$allowed_sources)) {
throw new \InvalidArgumentException('Invalid source "' . $source . '""');
}
$subscriber->set('source', $source);
return $subscriber;
}
}

View File

@@ -16,6 +16,7 @@ use MailPoet\Models\SubscriberIP;
use MailPoet\Models\Segment;
use MailPoet\Models\Setting;
use MailPoet\Models\SubscriberSegment;
use MailPoet\Subscribers\Source;
class SubscribersTest extends \MailPoetTest {
function _before() {
@@ -29,7 +30,8 @@ class SubscribersTest extends \MailPoetTest {
'email' => 'john@mailpoet.com',
'first_name' => 'John',
'last_name' => 'Doe',
'status' => Subscriber::STATUS_UNCONFIRMED
'status' => Subscriber::STATUS_UNCONFIRMED,
'source' => Source::API,
));
$this->subscriber_2 = Subscriber::createOrUpdate(array(
'email' => 'jane@mailpoet.com',
@@ -39,7 +41,8 @@ class SubscribersTest extends \MailPoetTest {
'segments' => array(
$this->segment_1->id,
$this->segment_2->id
)
),
'source' => Source::API,
));
$this->form = Form::createOrUpdate(array(
@@ -125,6 +128,7 @@ class SubscribersTest extends \MailPoetTest {
expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST);
expect($response->errors[0]['message'])
->equals('Your email address is invalid!');
expect($subscriber->source)->equals('administrator');
}
function testItCanSaveAnExistingSubscriber() {
@@ -140,9 +144,9 @@ class SubscribersTest extends \MailPoetTest {
Subscriber::findOne($this->subscriber_2->id)->asArray()
);
expect($response->data['first_name'])->equals('Super Jane');
expect($response->data['source'])->equals('api');
}
function testItCanRemoveListsFromAnExistingSubscriber() {
$router = new Subscribers();
$subscriber_data = $this->subscriber_2->asArray();

View File

@@ -294,6 +294,7 @@ class APITest extends \MailPoetTest {
expect($result['id'])->greaterThan(0);
expect($result['email'])->equals($subscriber['email']);
expect($result['cf_' . $custom_field->id])->equals('test');
expect($result['source'])->equals('api');
}
function testItSubscribesToSegmentsWhenAddingSubscriber() {

View File

@@ -452,6 +452,8 @@ class ImportTest extends \MailPoetTest {
expect($new_subscribers)->count(2);
expect($new_subscribers[0]->status)->equals('subscribed');
expect($new_subscribers[1]->status)->equals('subscribed');
expect($new_subscribers[0]->source)->equals('imported');
expect($new_subscribers[1]->source)->equals('imported');
}
function testItRunsImport() {

View File

@@ -0,0 +1,39 @@
<?php
namespace MailPoet\Subscribers;
use MailPoet\Models\Subscriber;
class SourceTest extends \MailPoetTest {
function testItDoesntOverrideSource() {
$subscriber = Subscriber::createOrUpdate(array(
'source' => Source::FORM,
));
$updated_subscriber = Source::setSource($subscriber, Source::API);
expect($updated_subscriber->source)->equals(Source::FORM);
}
function testItDoesntAllowInvalidSource() {
$subscriber = Subscriber::createOrUpdate(array(
'source' => Source::UNKNOWN,
));
$this->setExpectedException('\InvalidArgumentException');
Source::setSource($subscriber, 'invalid source');
}
function testItWorksWhenNoSourceIsSet() {
$subscriber = Subscriber::createOrUpdate(array());
$updated_subscriber = Source::setSource($subscriber, Source::FORM);
expect($updated_subscriber->source)->equals(Source::FORM);
}
function testItWorks() {
$subscriber = Subscriber::createOrUpdate(array(
'source' => Source::UNKNOWN,
));
$updated_subscriber = Source::setSource($subscriber, Source::FORM);
expect($updated_subscriber->source)->equals(Source::FORM);
}
}