diff --git a/lib/Models/Subscriber.php b/lib/Models/Subscriber.php index 428290de7c..ef2d3b3f04 100644 --- a/lib/Models/Subscriber.php +++ b/lib/Models/Subscriber.php @@ -230,10 +230,12 @@ class Subscriber extends Model { $subscriber->sendConfirmationEmail(); // welcome email - Scheduler::scheduleSubscriberWelcomeNotification( - $subscriber->id, - $segment_ids - ); + if($subscriber->status === self::STATUS_SUBSCRIBED) { + Scheduler::scheduleSubscriberWelcomeNotification( + $subscriber->id, + $segment_ids + ); + } } return $subscriber; diff --git a/lib/Subscription/Pages.php b/lib/Subscription/Pages.php index ebb082aa5c..e1173b1248 100644 --- a/lib/Subscription/Pages.php +++ b/lib/Subscription/Pages.php @@ -6,7 +6,9 @@ use MailPoet\Models\SubscriberSegment; use MailPoet\Models\CustomField; use MailPoet\Models\Setting; use MailPoet\Models\Segment; -use MailPoet\Util\Url; +use MailPoet\Newsletter\Scheduler\Scheduler; +use MailPoet\Util\Helpers; +use MailPoet\Util\Url as UrlHelper; use MailPoet\Subscription; use MailPoet\Form\Renderer as FormRenderer; use MailPoet\Form\Block\Date as FormBlockDate; @@ -63,14 +65,25 @@ class Pages { $subscriber_data = $this->subscriber->getUnconfirmedData(); $this->subscriber->status = Subscriber::STATUS_SUBSCRIBED; - $this->subscriber->confirmed_ip = $_SERVER['REMOTE_ADDR']; + $this->subscriber->confirmed_ip = (!empty($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : null; $this->subscriber->setExpr('confirmed_at', 'NOW()'); $this->subscriber->unconfirmed_data = null; $this->subscriber->save(); - // update subscriber from stored data after confirmation - if(!empty($subscriber_data)) { - Subscriber::createOrUpdate($subscriber_data); + if($this->subscriber->getErrors() === false) { + // send welcome notification + $subsciber_segments = $this->subscriber->segments()->findArray(); + if($subsciber_segments) { + Scheduler::scheduleSubscriberWelcomeNotification( + $this->subscriber->id, + Helpers::arrayColumn($subsciber_segments, 'id') + ); + } + + // update subscriber from stored data after confirmation + if(!empty($subscriber_data)) { + Subscriber::createOrUpdate($subscriber_data); + } } } @@ -346,7 +359,7 @@ class Pages { ' value="mailpoet_subscription_update" />'; $form_html .= ''; $form_html .= ''; + 'value="'.UrlHelper::getCurrentUrl().'" />'; $form_html .= ''; @@ -404,7 +417,7 @@ class Pages { : __('Manage your subscription', 'mailpoet') ); - return 'subscriber ).'">'.$text.''; } diff --git a/tests/unit/Models/SubscriberTest.php b/tests/unit/Models/SubscriberTest.php index a76245e85a..af22e364d3 100644 --- a/tests/unit/Models/SubscriberTest.php +++ b/tests/unit/Models/SubscriberTest.php @@ -3,7 +3,11 @@ use Carbon\Carbon; use Codeception\Util\Fixtures; use MailPoet\Models\CustomField; +use MailPoet\Models\Newsletter; +use MailPoet\Models\NewsletterOption; +use MailPoet\Models\NewsletterOptionField; use MailPoet\Models\Segment; +use MailPoet\Models\SendingQueue; use MailPoet\Models\Setting; use MailPoet\Models\Subscriber; use MailPoet\Models\SubscriberCustomField; @@ -414,6 +418,100 @@ class SubscriberTest extends MailPoetTest { 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(); + } + + $signup_confirmation_enabled = (bool)Setting::setValue( + 'signup_confirmation.enabled', false + ); + $subscriber = Subscriber::subscribe($this->data, array($segment->id())); + expect($subscriber->id() > 0)->equals(true); + expect($subscriber->segments()->count())->equals(1); + $scheduled_notification = SendingQueue::where('newsletter_id', $newsletter->id) + ->where('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(); + } + + $signup_confirmation_enabled = (bool)Setting::setValue( + 'signup_confirmation.enabled', true + ); + $subscriber = Subscriber::subscribe($this->data, array($segment->id())); + expect($subscriber->id() > 0)->equals(true); + expect($subscriber->segments()->count())->equals(1); + $scheduled_notification = SendingQueue::where('newsletter_id', $newsletter->id) + ->where('status', SendingQueue::STATUS_SCHEDULED) + ->findOne(); + expect($scheduled_notification)->notEmpty(); + } + function testItCannotSubscribeWithReservedColumns() { $segment = Segment::create(); $segment->hydrate(array('name' => 'List #1')); @@ -943,5 +1041,9 @@ class SubscriberTest extends MailPoetTest { ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table); ORM::raw_execute('TRUNCATE ' . CustomField::$_table); ORM::raw_execute('TRUNCATE ' . SubscriberCustomField::$_table); + ORM::raw_execute('TRUNCATE ' . Newsletter::$_table); + ORM::raw_execute('TRUNCATE ' . NewsletterOptionField::$_table); + ORM::raw_execute('TRUNCATE ' . NewsletterOption::$_table); + ORM::raw_execute('TRUNCATE ' . Setting::$_table); } } \ No newline at end of file diff --git a/tests/unit/Subscription/PagesTest.php b/tests/unit/Subscription/PagesTest.php new file mode 100644 index 0000000000..712835dac4 --- /dev/null +++ b/tests/unit/Subscription/PagesTest.php @@ -0,0 +1,91 @@ +subscriber = Subscriber::create(); + $this->subscriber->hydrate(Fixtures::get('subscriber_template')); + $this->subscriber->status = Subscriber::STATUS_UNCONFIRMED; + $this->subscriber->save(); + expect($this->subscriber->getErrors())->false(); + $this->data['email'] = $this->subscriber->email; + $this->data['token'] = Subscriber::generateToken($this->subscriber->email); + $this->subscription = new Pages($action = false, $this->data); + } + + function testItConfirmsSubscription() { + $this->subscription->confirm(); + $confirmed_subscriber = Subscriber::findOne($this->subscriber->id); + expect($confirmed_subscriber->status)->equals(Subscriber::STATUS_SUBSCRIBED); + } + + function testItSendsWelcomeNotificationUponConfirmingSubscription() { + // create segment + $segment = Segment::create(); + $segment->hydrate(array('name' => 'List #1')); + $segment->save(); + expect($segment->getErrors())->false(); + // create subscriber->segment relation + $subscriber_segment = SubscriberSegment::create(); + $subscriber_segment->hydrate( + array( + 'subscriber_id' => $this->subscriber->id, + 'segment_id' => $segment->id + ) + ); + $subscriber_segment->save(); + expect($subscriber_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(); + } + + // confirm subscription and ensure that welcome email is scheduled + $this->subscription->confirm(); + $scheduled_notification = SendingQueue::where('newsletter_id', $newsletter->id) + ->where('status', SendingQueue::STATUS_SCHEDULED) + ->findOne(); + expect($scheduled_notification)->notEmpty(); + } + + function _after() { + ORM::raw_execute('TRUNCATE ' . Subscriber::$_table); + ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table); + ORM::raw_execute('TRUNCATE ' . Newsletter::$_table); + ORM::raw_execute('TRUNCATE ' . Segment::$_table); + ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table); + ORM::raw_execute('TRUNCATE ' . NewsletterOption::$_table); + ORM::raw_execute('TRUNCATE ' . NewsletterOptionField::$_table); + } +}