From 7528f0f52be28dddc2e19f96bae1ece458000fa9 Mon Sep 17 00:00:00 2001 From: wxa Date: Wed, 20 Feb 2019 15:16:02 +0300 Subject: [PATCH] Move subscribe() method to a separate class an make it non-static [MAILPOET-1825] --- lib/DI/ContainerConfigurator.php | 1 + lib/Models/Subscriber.php | 67 ---- lib/Subscribers/SubscriberActions.php | 97 ++++++ tests/integration/Models/SubscriberTest.php | 270 --------------- .../Subscribers/SubscriberActionsTest.php | 323 ++++++++++++++++++ 5 files changed, 421 insertions(+), 337 deletions(-) create mode 100644 lib/Subscribers/SubscriberActions.php create mode 100644 tests/integration/Subscribers/SubscriberActionsTest.php diff --git a/lib/DI/ContainerConfigurator.php b/lib/DI/ContainerConfigurator.php index 059e829ad7..3437a5b26a 100644 --- a/lib/DI/ContainerConfigurator.php +++ b/lib/DI/ContainerConfigurator.php @@ -78,6 +78,7 @@ class ContainerConfigurator implements IContainerConfigurator { $container->autowire(\MailPoet\Subscribers\NewSubscriberNotificationMailer::class)->setPublic(true); $container->autowire(\MailPoet\Subscribers\ConfirmationEmailMailer::class)->setPublic(true); $container->autowire(\MailPoet\Subscribers\RequiredCustomFieldValidator::class)->setPublic(true); + $container->autowire(\MailPoet\Subscribers\SubscriberActions::class)->setPublic(true); // Segments $container->autowire(\MailPoet\Segments\SubscribersListings::class)->setPublic(true); $container->autowire(\MailPoet\Segments\WooCommerce::class)->setPublic(true); diff --git a/lib/Models/Subscriber.php b/lib/Models/Subscriber.php index 0539866dda..681e7b21ef 100644 --- a/lib/Models/Subscriber.php +++ b/lib/Models/Subscriber.php @@ -117,73 +117,6 @@ class Subscriber extends Model { ); } - static function subscribe($subscriber_data = array(), $segment_ids = array()) { - // filter out keys from the subscriber_data array - // that should not be editable when subscribing - $subscriber_data = self::filterOutReservedColumns($subscriber_data); - - $settings = new SettingsController(); - $signup_confirmation_enabled = (bool)$settings->get( - 'signup_confirmation.enabled' - ); - - $subscriber_data['subscribed_ip'] = Helpers::getIP(); - - $subscriber = self::findOne($subscriber_data['email']); - - if ($subscriber === false || !$signup_confirmation_enabled) { - // 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; - } - - $subscriber = self::findOne($subscriber->id); - } else { - // store subscriber data to be updated after confirmation - $subscriber->setUnconfirmedData($subscriber_data); - $subscriber->setExpr('updated_at', 'NOW()'); - } - - // restore trashed subscriber - if ($subscriber->deleted_at !== null) { - $subscriber->setExpr('deleted_at', 'NULL'); - } - - // set status depending on signup confirmation setting - if ($subscriber->status !== self::STATUS_SUBSCRIBED) { - if ($signup_confirmation_enabled === true) { - $subscriber->set('status', self::STATUS_UNCONFIRMED); - } else { - $subscriber->set('status', self::STATUS_SUBSCRIBED); - } - } - - $subscriber = Source::setSource($subscriber, Source::FORM); - - if ($subscriber->save()) { - // link subscriber to segments - SubscriberSegment::subscribeToSegments($subscriber, $segment_ids); - - $sender = new ConfirmationEmailMailer(); - $sender->sendConfirmationEmail($subscriber); - - if ($subscriber->status === self::STATUS_SUBSCRIBED) { - $sender = new NewSubscriberNotificationMailer(); - $sender->send($subscriber, Segment::whereIn('id', $segment_ids)->findMany()); - - Scheduler::scheduleSubscriberWelcomeNotification( - $subscriber->id, - $segment_ids - ); - } - } - - return $subscriber; - } - static function filterOutReservedColumns(array $subscriber_data) { $reserved_columns = array( 'id', diff --git a/lib/Subscribers/SubscriberActions.php b/lib/Subscribers/SubscriberActions.php new file mode 100644 index 0000000000..1dfac83a3b --- /dev/null +++ b/lib/Subscribers/SubscriberActions.php @@ -0,0 +1,97 @@ +settings = $settings; + $this->new_subscriber_notification_mailer = $new_subscriber_notification_mailer; + $this->confirmation_email_mailer = $confirmation_email_mailer; + } + + function subscribe($subscriber_data = array(), $segment_ids = array()) { + // filter out keys from the subscriber_data array + // that should not be editable when subscribing + $subscriber_data = Subscriber::filterOutReservedColumns($subscriber_data); + + $signup_confirmation_enabled = (bool)$this->settings->get( + 'signup_confirmation.enabled' + ); + + $subscriber_data['subscribed_ip'] = Helpers::getIP(); + + $subscriber = Subscriber::findOne($subscriber_data['email']); + + if ($subscriber === false || !$signup_confirmation_enabled) { + // create new subscriber or update if no confirmation is required + $subscriber = Subscriber::createOrUpdate($subscriber_data); + if ($subscriber->getErrors() !== false) { + $subscriber = Source::setSource($subscriber, Source::FORM); + $subscriber->save(); + return $subscriber; + } + + $subscriber = Subscriber::findOne($subscriber->id); + } else { + // store subscriber data to be updated after confirmation + $subscriber->setUnconfirmedData($subscriber_data); + $subscriber->setExpr('updated_at', 'NOW()'); + } + + // restore trashed subscriber + if ($subscriber->deleted_at !== null) { + $subscriber->setExpr('deleted_at', 'NULL'); + } + + // set status depending on signup confirmation setting + if ($subscriber->status !== Subscriber::STATUS_SUBSCRIBED) { + if ($signup_confirmation_enabled === true) { + $subscriber->set('status', Subscriber::STATUS_UNCONFIRMED); + } else { + $subscriber->set('status', Subscriber::STATUS_SUBSCRIBED); + } + } + + $subscriber = Source::setSource($subscriber, Source::FORM); + + if ($subscriber->save()) { + // link subscriber to segments + SubscriberSegment::subscribeToSegments($subscriber, $segment_ids); + + $this->confirmation_email_mailer->sendConfirmationEmail($subscriber); + + if ($subscriber->status === Subscriber::STATUS_SUBSCRIBED) { + $this->new_subscriber_notification_mailer->send($subscriber, Segment::whereIn('id', $segment_ids)->findMany()); + + Scheduler::scheduleSubscriberWelcomeNotification( + $subscriber->id, + $segment_ids + ); + } + } + + return $subscriber; + } + +} diff --git a/tests/integration/Models/SubscriberTest.php b/tests/integration/Models/SubscriberTest.php index ce53a93f38..e3b5c8fd65 100644 --- a/tests/integration/Models/SubscriberTest.php +++ b/tests/integration/Models/SubscriberTest.php @@ -428,274 +428,6 @@ class SubscriberTest extends \MailPoetTest { expect($subscribers[0]['status'])->equals('unsubscribed'); } - function testItCanSubscribe() { - $segment = Segment::create(); - $segment->hydrate(array('name' => 'List #1')); - $segment->save(); - - $segment2 = Segment::create(); - $segment2->hydrate(array('name' => 'List #2')); - $segment2->save(); - - $subscriber = Subscriber::subscribe( - $this->test_data, - array($segment->id(), $segment2->id()) - ); - - expect($subscriber->id() > 0)->equals(true); - expect($subscriber->segments()->count())->equals(2); - expect($subscriber->email)->equals($this->test_data['email']); - expect($subscriber->first_name)->equals($this->test_data['first_name']); - expect($subscriber->last_name)->equals($this->test_data['last_name']); - // signup confirmation is enabled by default - expect($subscriber->status)->equals(Subscriber::STATUS_UNCONFIRMED); - expect($subscriber->deleted_at)->equals(null); - } - - function testItSchedulesWelcomeNotificationUponSubscriptionWhenSubscriptionConfirmationIsDisabled() { - // create segment - $segment = Segment::create(); - $segment->hydrate(array('name' => 'List #1')); - $segment->save(); - expect($segment->getErrors())->false(); - - // create welcome notification newsletter and relevant scheduling options - $newsletter = Newsletter::create(); - $newsletter->type = Newsletter::TYPE_WELCOME; - $newsletter->status = Newsletter::STATUS_ACTIVE; - $newsletter->save(); - expect($newsletter->getErrors())->false(); - - $newsletter_options = array( - 'event' => 'segment', - 'segment' => $segment->id, - 'afterTimeType' => 'days', - 'afterTimeNumber' => 1 - ); - foreach ($newsletter_options as $option => $value) { - $newsletter_option_field = NewsletterOptionField::create(); - $newsletter_option_field->name = $option; - $newsletter_option_field->newsletter_type = $newsletter->type; - $newsletter_option_field->save(); - expect($newsletter_option_field->getErrors())->false(); - - $newsletter_option = NewsletterOption::create(); - $newsletter_option->option_field_id = $newsletter_option_field->id; - $newsletter_option->newsletter_id = $newsletter->id; - $newsletter_option->value = $value; - $newsletter_option->save(); - expect($newsletter_option->getErrors())->false(); - } - - $this->settings->set('signup_confirmation.enabled', false); - $subscriber = Subscriber::subscribe($this->test_data, array($segment->id())); - expect($subscriber->id() > 0)->equals(true); - expect($subscriber->segments()->count())->equals(1); - $scheduled_notification = SendingQueue::findTaskByNewsletterId($newsletter->id) - ->where('tasks.status', SendingQueue::STATUS_SCHEDULED) - ->findOne(); - expect($scheduled_notification)->notEmpty(); - } - - function testItDoesNotScheduleWelcomeNotificationUponSubscriptionWhenSubscriptionConfirmationIsEnabled() { - // create segment - $segment = Segment::create(); - $segment->hydrate(array('name' => 'List #1')); - $segment->save(); - expect($segment->getErrors())->false(); - - // create welcome notification newsletter and relevant scheduling options - $newsletter = Newsletter::create(); - $newsletter->type = Newsletter::TYPE_WELCOME; - $newsletter->status = Newsletter::STATUS_ACTIVE; - $newsletter->save(); - expect($newsletter->getErrors())->false(); - - $newsletter_options = array( - 'event' => 'segment', - 'segment' => $segment->id, - 'afterTimeType' => 'days', - 'afterTimeNumber' => 1 - ); - foreach ($newsletter_options as $option => $value) { - $newsletter_option_field = NewsletterOptionField::create(); - $newsletter_option_field->name = $option; - $newsletter_option_field->newsletter_type = $newsletter->type; - $newsletter_option_field->save(); - expect($newsletter_option_field->getErrors())->false(); - - $newsletter_option = NewsletterOption::create(); - $newsletter_option->option_field_id = $newsletter_option_field->id; - $newsletter_option->newsletter_id = $newsletter->id; - $newsletter_option->value = $value; - $newsletter_option->save(); - expect($newsletter_option->getErrors())->false(); - } - - $this->settings->set('signup_confirmation.enabled', true); - $subscriber = Subscriber::subscribe($this->test_data, array($segment->id())); - expect($subscriber->id() > 0)->equals(true); - expect($subscriber->segments()->count())->equals(1); - $scheduled_notification = SendingQueue::findTaskByNewsletterId($newsletter->id) - ->where('tasks.status', SendingQueue::STATUS_SCHEDULED) - ->findOne(); - expect($scheduled_notification)->isEmpty(); - } - - function testItCannotSubscribeWithReservedColumns() { - $segment = Segment::create(); - $segment->hydrate(array('name' => 'List #1')); - $segment->save(); - - $subscriber = Subscriber::subscribe( - array( - 'email' => 'donald@mailpoet.com', - 'first_name' => 'Donald', - 'last_name' => 'Trump', - // the fields below should NOT be taken into account - 'id' => 1337, - 'wp_user_id' => 7331, - 'is_woocommerce_user' => 1, - 'status' => Subscriber::STATUS_SUBSCRIBED, - 'created_at' => '1984-03-09 00:00:01', - 'updated_at' => '1984-03-09 00:00:02', - 'deleted_at' => '1984-03-09 00:00:03' - ), - array($segment->id()) - ); - - expect($subscriber->id > 0)->equals(true); - expect($subscriber->id)->notEquals(1337); - expect($subscriber->segments()->count())->equals(1); - expect($subscriber->email)->equals('donald@mailpoet.com'); - expect($subscriber->first_name)->equals('Donald'); - expect($subscriber->last_name)->equals('Trump'); - - expect($subscriber->wp_user_id)->equals(null); - expect($subscriber->is_woocommerce_user)->equals(0); - expect($subscriber->status)->equals(Subscriber::STATUS_UNCONFIRMED); - expect($subscriber->created_at)->notEquals('1984-03-09 00:00:01'); - expect($subscriber->updated_at)->notEquals('1984-03-09 00:00:02'); - expect($subscriber->created_at)->equals($subscriber->updated_at); - expect($subscriber->deleted_at)->equals(null); - } - - function testItOverwritesSubscriberDataWhenConfirmationIsDisabled() { - $original_setting_value = $this->settings->get('signup_confirmation.enabled'); - $this->settings->set('signup_confirmation.enabled', false); - - $segment = Segment::create(); - $segment->hydrate(array('name' => 'List #1')); - $segment->save(); - - $segment2 = Segment::create(); - $segment2->hydrate(array('name' => 'List #2')); - $segment2->save(); - - $data = array( - 'email' => 'some@example.com', - 'first_name' => 'Some', - 'last_name' => 'Example', - ); - - $subscriber = Subscriber::subscribe( - $data, - array($segment->id()) - ); - - expect($subscriber->id() > 0)->equals(true); - expect($subscriber->segments()->count())->equals(1); - expect($subscriber->email)->equals($data['email']); - expect($subscriber->first_name)->equals($data['first_name']); - expect($subscriber->last_name)->equals($data['last_name']); - - $data2 = $data; - $data2['first_name'] = 'Aaa'; - $data2['last_name'] = 'Bbb'; - - $subscriber = Subscriber::subscribe( - $data2, - array($segment->id(), $segment2->id()) - ); - - expect($subscriber->id() > 0)->equals(true); - expect($subscriber->segments()->count())->equals(2); - expect($subscriber->email)->equals($data2['email']); - expect($subscriber->first_name)->equals($data2['first_name']); - expect($subscriber->last_name)->equals($data2['last_name']); - - $this->settings->set('signup_confirmation.enabled', $original_setting_value); - } - - function testItStoresUnconfirmedSubscriberDataWhenConfirmationIsEnabled() { - $original_setting_value = $this->settings->get('signup_confirmation.enabled'); - $this->settings->set('signup_confirmation.enabled', true); - - $segment = Segment::create(); - $segment->hydrate(array('name' => 'List #1')); - $segment->save(); - - $segment2 = Segment::create(); - $segment2->hydrate(array('name' => 'List #2')); - $segment2->save(); - - $data = array( - 'email' => 'some@example.com', - 'first_name' => 'Some', - 'last_name' => 'Example', - ); - - $subscriber = Subscriber::subscribe( - $data, - array($segment->id()) - ); - - expect($subscriber->id() > 0)->equals(true); - expect($subscriber->segments()->count())->equals(1); - expect($subscriber->email)->equals($data['email']); - expect($subscriber->first_name)->equals($data['first_name']); - expect($subscriber->last_name)->equals($data['last_name']); - - expect($subscriber->unconfirmed_data)->isEmpty(); - - $data2 = $data; - $data2['first_name'] = 'Aaa'; - $data2['last_name'] = 'Bbb'; - - $subscriber = Subscriber::subscribe( - $data2, - array($segment->id(), $segment2->id()) - ); - - expect($subscriber->id() > 0)->equals(true); - expect($subscriber->segments()->count())->equals(2); - // fields should be left intact - expect($subscriber->email)->equals($data['email']); - expect($subscriber->first_name)->equals($data['first_name']); - expect($subscriber->last_name)->equals($data['last_name']); - - expect($subscriber->unconfirmed_data)->notEmpty(); - expect($subscriber->unconfirmed_data)->equals(json_encode($data2)); - - // Unconfirmed data should be wiped after any direct update - // during confirmation, manual admin editing - $subscriber = Subscriber::createOrUpdate($data2); - expect($subscriber->unconfirmed_data)->isEmpty(); - // during import - $subscriber->unconfirmed_data = json_encode($data2); - $subscriber->save(); - expect($subscriber->isDirty('unconfirmed_data'))->false(); - expect($subscriber->unconfirmed_data)->notEmpty(); - Subscriber::updateMultiple( - array_keys($data2), - array(array_values($data2)) - ); - $subscriber = Subscriber::where('email', $data2['email'])->findOne(); - expect($subscriber->unconfirmed_data)->isEmpty(); - - $this->settings->set('signup_confirmation.enabled', $original_setting_value); - } - function testItCanBeUpdatedByEmail() { $subscriber_updated = Subscriber::createOrUpdate(array( 'email' => $this->test_data['email'], @@ -1155,8 +887,6 @@ class SubscriberTest extends \MailPoetTest { function _after() { \ORM::raw_execute('TRUNCATE ' . Subscriber::$_table); \ORM::raw_execute('TRUNCATE ' . Segment::$_table); - \ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table); - \ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table); \ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table); \ORM::raw_execute('TRUNCATE ' . CustomField::$_table); \ORM::raw_execute('TRUNCATE ' . SubscriberCustomField::$_table); diff --git a/tests/integration/Subscribers/SubscriberActionsTest.php b/tests/integration/Subscribers/SubscriberActionsTest.php new file mode 100644 index 0000000000..a178dc4317 --- /dev/null +++ b/tests/integration/Subscribers/SubscriberActionsTest.php @@ -0,0 +1,323 @@ +test_data = array( + 'first_name' => 'John', + 'last_name' => 'Mailer', + 'email' => 'john@mailpoet.com' + ); + $this->subscriber_actions = ContainerWrapper::getInstance()->get(SubscriberActions::class); + $this->settings = new SettingsController(); + $this->settings->set('sender', array( + 'name' => 'John Doe', + 'address' => 'john.doe@example.com' + )); + } + + function testItCanSubscribe() { + $segment = Segment::create(); + $segment->hydrate(array('name' => 'List #1')); + $segment->save(); + + $segment2 = Segment::create(); + $segment2->hydrate(array('name' => 'List #2')); + $segment2->save(); + + $subscriber = $this->subscriber_actions->subscribe( + $this->test_data, + array($segment->id(), $segment2->id()) + ); + + expect($subscriber->id() > 0)->equals(true); + expect($subscriber->segments()->count())->equals(2); + expect($subscriber->email)->equals($this->test_data['email']); + expect($subscriber->first_name)->equals($this->test_data['first_name']); + expect($subscriber->last_name)->equals($this->test_data['last_name']); + // signup confirmation is enabled by default + expect($subscriber->status)->equals(Subscriber::STATUS_UNCONFIRMED); + expect($subscriber->deleted_at)->equals(null); + } + + function testItSchedulesWelcomeNotificationUponSubscriptionWhenSubscriptionConfirmationIsDisabled() { + // create segment + $segment = Segment::create(); + $segment->hydrate(array('name' => 'List #1')); + $segment->save(); + expect($segment->getErrors())->false(); + + // create welcome notification newsletter and relevant scheduling options + $newsletter = Newsletter::create(); + $newsletter->type = Newsletter::TYPE_WELCOME; + $newsletter->status = Newsletter::STATUS_ACTIVE; + $newsletter->save(); + expect($newsletter->getErrors())->false(); + + $newsletter_options = array( + 'event' => 'segment', + 'segment' => $segment->id, + 'afterTimeType' => 'days', + 'afterTimeNumber' => 1 + ); + foreach ($newsletter_options as $option => $value) { + $newsletter_option_field = NewsletterOptionField::create(); + $newsletter_option_field->name = $option; + $newsletter_option_field->newsletter_type = $newsletter->type; + $newsletter_option_field->save(); + expect($newsletter_option_field->getErrors())->false(); + + $newsletter_option = NewsletterOption::create(); + $newsletter_option->option_field_id = $newsletter_option_field->id; + $newsletter_option->newsletter_id = $newsletter->id; + $newsletter_option->value = $value; + $newsletter_option->save(); + expect($newsletter_option->getErrors())->false(); + } + + $this->settings->set('signup_confirmation.enabled', false); + $subscriber = $this->subscriber_actions->subscribe($this->test_data, array($segment->id())); + expect($subscriber->id() > 0)->equals(true); + expect($subscriber->segments()->count())->equals(1); + $scheduled_notification = SendingQueue::findTaskByNewsletterId($newsletter->id) + ->where('tasks.status', SendingQueue::STATUS_SCHEDULED) + ->findOne(); + expect($scheduled_notification)->notEmpty(); + } + + function testItDoesNotScheduleWelcomeNotificationUponSubscriptionWhenSubscriptionConfirmationIsEnabled() { + // create segment + $segment = Segment::create(); + $segment->hydrate(array('name' => 'List #1')); + $segment->save(); + expect($segment->getErrors())->false(); + + // create welcome notification newsletter and relevant scheduling options + $newsletter = Newsletter::create(); + $newsletter->type = Newsletter::TYPE_WELCOME; + $newsletter->status = Newsletter::STATUS_ACTIVE; + $newsletter->save(); + expect($newsletter->getErrors())->false(); + + $newsletter_options = array( + 'event' => 'segment', + 'segment' => $segment->id, + 'afterTimeType' => 'days', + 'afterTimeNumber' => 1 + ); + foreach ($newsletter_options as $option => $value) { + $newsletter_option_field = NewsletterOptionField::create(); + $newsletter_option_field->name = $option; + $newsletter_option_field->newsletter_type = $newsletter->type; + $newsletter_option_field->save(); + expect($newsletter_option_field->getErrors())->false(); + + $newsletter_option = NewsletterOption::create(); + $newsletter_option->option_field_id = $newsletter_option_field->id; + $newsletter_option->newsletter_id = $newsletter->id; + $newsletter_option->value = $value; + $newsletter_option->save(); + expect($newsletter_option->getErrors())->false(); + } + + $this->settings->set('signup_confirmation.enabled', true); + $subscriber = $this->subscriber_actions->subscribe($this->test_data, array($segment->id())); + expect($subscriber->id() > 0)->equals(true); + expect($subscriber->segments()->count())->equals(1); + $scheduled_notification = SendingQueue::findTaskByNewsletterId($newsletter->id) + ->where('tasks.status', SendingQueue::STATUS_SCHEDULED) + ->findOne(); + expect($scheduled_notification)->isEmpty(); + } + + function testItCannotSubscribeWithReservedColumns() { + $segment = Segment::create(); + $segment->hydrate(array('name' => 'List #1')); + $segment->save(); + + $subscriber = $this->subscriber_actions->subscribe( + array( + 'email' => 'donald@mailpoet.com', + 'first_name' => 'Donald', + 'last_name' => 'Trump', + // the fields below should NOT be taken into account + 'id' => 1337, + 'wp_user_id' => 7331, + 'is_woocommerce_user' => 1, + 'status' => Subscriber::STATUS_SUBSCRIBED, + 'created_at' => '1984-03-09 00:00:01', + 'updated_at' => '1984-03-09 00:00:02', + 'deleted_at' => '1984-03-09 00:00:03' + ), + array($segment->id()) + ); + + expect($subscriber->id > 0)->equals(true); + expect($subscriber->id)->notEquals(1337); + expect($subscriber->segments()->count())->equals(1); + expect($subscriber->email)->equals('donald@mailpoet.com'); + expect($subscriber->first_name)->equals('Donald'); + expect($subscriber->last_name)->equals('Trump'); + + expect($subscriber->wp_user_id)->equals(null); + expect($subscriber->is_woocommerce_user)->equals(0); + expect($subscriber->status)->equals(Subscriber::STATUS_UNCONFIRMED); + expect($subscriber->created_at)->notEquals('1984-03-09 00:00:01'); + expect($subscriber->updated_at)->notEquals('1984-03-09 00:00:02'); + expect($subscriber->created_at)->equals($subscriber->updated_at); + expect($subscriber->deleted_at)->equals(null); + } + + function testItOverwritesSubscriberDataWhenConfirmationIsDisabled() { + $original_setting_value = $this->settings->get('signup_confirmation.enabled'); + $this->settings->set('signup_confirmation.enabled', false); + + $segment = Segment::create(); + $segment->hydrate(array('name' => 'List #1')); + $segment->save(); + + $segment2 = Segment::create(); + $segment2->hydrate(array('name' => 'List #2')); + $segment2->save(); + + $data = array( + 'email' => 'some@example.com', + 'first_name' => 'Some', + 'last_name' => 'Example', + ); + + $subscriber = $this->subscriber_actions->subscribe( + $data, + array($segment->id()) + ); + + expect($subscriber->id() > 0)->equals(true); + expect($subscriber->segments()->count())->equals(1); + expect($subscriber->email)->equals($data['email']); + expect($subscriber->first_name)->equals($data['first_name']); + expect($subscriber->last_name)->equals($data['last_name']); + + $data2 = $data; + $data2['first_name'] = 'Aaa'; + $data2['last_name'] = 'Bbb'; + + $subscriber = $this->subscriber_actions->subscribe( + $data2, + array($segment->id(), $segment2->id()) + ); + + expect($subscriber->id() > 0)->equals(true); + expect($subscriber->segments()->count())->equals(2); + expect($subscriber->email)->equals($data2['email']); + expect($subscriber->first_name)->equals($data2['first_name']); + expect($subscriber->last_name)->equals($data2['last_name']); + + $this->settings->set('signup_confirmation.enabled', $original_setting_value); + } + + function testItStoresUnconfirmedSubscriberDataWhenConfirmationIsEnabled() { + $original_setting_value = $this->settings->get('signup_confirmation.enabled'); + $this->settings->set('signup_confirmation.enabled', true); + + $segment = Segment::create(); + $segment->hydrate(array('name' => 'List #1')); + $segment->save(); + + $segment2 = Segment::create(); + $segment2->hydrate(array('name' => 'List #2')); + $segment2->save(); + + $data = array( + 'email' => 'some@example.com', + 'first_name' => 'Some', + 'last_name' => 'Example', + ); + + $subscriber = $this->subscriber_actions->subscribe( + $data, + array($segment->id()) + ); + + expect($subscriber->id() > 0)->equals(true); + expect($subscriber->segments()->count())->equals(1); + expect($subscriber->email)->equals($data['email']); + expect($subscriber->first_name)->equals($data['first_name']); + expect($subscriber->last_name)->equals($data['last_name']); + + expect($subscriber->unconfirmed_data)->isEmpty(); + + $data2 = $data; + $data2['first_name'] = 'Aaa'; + $data2['last_name'] = 'Bbb'; + + $subscriber = $this->subscriber_actions->subscribe( + $data2, + array($segment->id(), $segment2->id()) + ); + + expect($subscriber->id() > 0)->equals(true); + expect($subscriber->segments()->count())->equals(2); + // fields should be left intact + expect($subscriber->email)->equals($data['email']); + expect($subscriber->first_name)->equals($data['first_name']); + expect($subscriber->last_name)->equals($data['last_name']); + + expect($subscriber->unconfirmed_data)->notEmpty(); + expect($subscriber->unconfirmed_data)->equals(json_encode($data2)); + + // Unconfirmed data should be wiped after any direct update + // during confirmation, manual admin editing + $subscriber = Subscriber::createOrUpdate($data2); + expect($subscriber->unconfirmed_data)->isEmpty(); + // during import + $subscriber->unconfirmed_data = json_encode($data2); + $subscriber->save(); + expect($subscriber->isDirty('unconfirmed_data'))->false(); + expect($subscriber->unconfirmed_data)->notEmpty(); + Subscriber::updateMultiple( + array_keys($data2), + array(array_values($data2)) + ); + $subscriber = Subscriber::where('email', $data2['email'])->findOne(); + expect($subscriber->unconfirmed_data)->isEmpty(); + + $this->settings->set('signup_confirmation.enabled', $original_setting_value); + } + + function _after() { + \ORM::raw_execute('TRUNCATE ' . Subscriber::$_table); + \ORM::raw_execute('TRUNCATE ' . Segment::$_table); + \ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table); + \ORM::raw_execute('TRUNCATE ' . Newsletter::$_table); + \ORM::raw_execute('TRUNCATE ' . NewsletterOptionField::$_table); + \ORM::raw_execute('TRUNCATE ' . NewsletterOption::$_table); + \ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table); + \ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table); + \ORM::raw_execute('TRUNCATE ' . Setting::$_table); + } +}