diff --git a/mailpoet/lib/AutomaticEmails/WooCommerce/Events/AbandonedCart.php b/mailpoet/lib/AutomaticEmails/WooCommerce/Events/AbandonedCart.php index 76cf7420b0..62b52d4935 100644 --- a/mailpoet/lib/AutomaticEmails/WooCommerce/Events/AbandonedCart.php +++ b/mailpoet/lib/AutomaticEmails/WooCommerce/Events/AbandonedCart.php @@ -165,11 +165,11 @@ class AbandonedCart { } $meta = [self::TASK_META_NAME => $cartProductIds]; - $this->scheduler->scheduleOrRescheduleAutomaticEmail(WooCommerceEmail::SLUG, self::SLUG, $subscriber->getId(), $meta); + $this->scheduler->scheduleOrRescheduleAutomaticEmail(WooCommerceEmail::SLUG, self::SLUG, (int)$subscriber->getId(), $meta); } private function rescheduleAbandonedCartEmail(SubscriberEntity $subscriberEntity) { - $this->scheduler->rescheduleAutomaticEmail(WooCommerceEmail::SLUG, self::SLUG, $subscriberEntity->getId()); + $this->scheduler->rescheduleAutomaticEmail(WooCommerceEmail::SLUG, self::SLUG, (int)$subscriberEntity->getId()); } private function cancelAbandonedCartEmail() { @@ -177,7 +177,7 @@ class AbandonedCart { if (!$subscriber) { return; } - $this->scheduler->cancelAutomaticEmail(WooCommerceEmail::SLUG, self::SLUG, $subscriber->getId()); + $this->scheduler->cancelAutomaticEmail(WooCommerceEmail::SLUG, self::SLUG, (int)$subscriber->getId()); } private function getSubscriber(): ?SubscriberEntity { diff --git a/mailpoet/lib/Newsletter/NewslettersRepository.php b/mailpoet/lib/Newsletter/NewslettersRepository.php index 6648493e14..e87c807e1d 100644 --- a/mailpoet/lib/Newsletter/NewslettersRepository.php +++ b/mailpoet/lib/Newsletter/NewslettersRepository.php @@ -65,6 +65,30 @@ class NewslettersRepository extends Repository { ->getResult(); } + /** + * @return NewsletterEntity[] + */ + public function findActiveByTypeAndGroup(string $type, ?string $group): array { + $qb = $this->entityManager + ->createQueryBuilder() + ->select('n') + ->from(NewsletterEntity::class, 'n') + ->where('n.status = :status') + ->setParameter(':status', NewsletterEntity::STATUS_ACTIVE) + ->andWhere('n.deletedAt IS NULL') + ->andWhere('n.type = :type') + ->setParameter('type', $type); + + if ($group) { + $qb->join('n.options', 'o', Join::WITH, 'o.value = :group') + ->join('o.optionField', 'f', Join::WITH, 'f.name = :nameGroup AND f.newsletterType = :type') + ->setParameter('nameGroup', NewsletterOptionFieldEntity::NAME_GROUP) + ->setParameter('group', $group); + } + + return $qb->getQuery()->getResult(); + } + /** * @param string[] $types * @return NewsletterEntity[] diff --git a/mailpoet/lib/Newsletter/Scheduler/Scheduler.php b/mailpoet/lib/Newsletter/Scheduler/Scheduler.php index 1fe3a48ef4..4d0e3bff6d 100644 --- a/mailpoet/lib/Newsletter/Scheduler/Scheduler.php +++ b/mailpoet/lib/Newsletter/Scheduler/Scheduler.php @@ -2,7 +2,8 @@ namespace MailPoet\Newsletter\Scheduler; -use MailPoet\Models\Newsletter; +use MailPoet\Entities\NewsletterEntity; +use MailPoet\Newsletter\NewslettersRepository; use MailPoet\WP\Functions as WPFunctions; use MailPoetVendor\Carbon\Carbon; @@ -12,10 +13,15 @@ class Scheduler { /** @var WPFunctions */ private $wp; + /** @var NewslettersRepository */ + private $newslettersRepository; + public function __construct( - WPFunctions $wp + WPFunctions $wp, + NewslettersRepository $newslettersRepository ) { $this->wp = $wp; + $this->newslettersRepository = $newslettersRepository; } public function getNextRunDate($schedule, $fromTimestamp = false) { @@ -65,12 +71,11 @@ class Scheduler { return $currentTime; } - public function getNewsletters($type, $group = false) { - return Newsletter::getPublished() - ->filter('filterType', $type, $group) - ->filter('filterStatus', Newsletter::STATUS_ACTIVE) - ->filter('filterWithOptions', $type) - ->findMany(); + /** + * @return NewsletterEntity[] + */ + public function getNewsletters(string $type, ?string $group = null): array { + return $this->newslettersRepository->findActiveByTypeAndGroup($type, $group); } public function formatDatetimeString($datetimeString) { diff --git a/mailpoet/tests/integration/AutomaticEmails/WooCommerce/Events/AbandonedCartTest.php b/mailpoet/tests/integration/AutomaticEmails/WooCommerce/Events/AbandonedCartTest.php index 0764fb6a0f..461125b10c 100644 --- a/mailpoet/tests/integration/AutomaticEmails/WooCommerce/Events/AbandonedCartTest.php +++ b/mailpoet/tests/integration/AutomaticEmails/WooCommerce/Events/AbandonedCartTest.php @@ -10,6 +10,7 @@ use MailPoet\Entities\ScheduledTaskEntity; use MailPoet\Entities\ScheduledTaskSubscriberEntity; use MailPoet\Entities\SendingQueueEntity; use MailPoet\Entities\SubscriberEntity; +use MailPoet\Newsletter\NewslettersRepository; use MailPoet\Newsletter\Options\NewsletterOptionFieldsRepository; use MailPoet\Newsletter\Options\NewsletterOptionsRepository; use MailPoet\Newsletter\Scheduler\AutomaticEmailScheduler; @@ -99,7 +100,7 @@ class AbandonedCartTest extends \MailPoetTest { $this->wp = $wp; WPFunctions::set($this->wp); - $this->automaticEmailScheduler = new AutomaticEmailScheduler(new Scheduler($this->wp)); + $this->automaticEmailScheduler = new AutomaticEmailScheduler(new Scheduler($this->wp, $this->diContainer->get(NewslettersRepository::class))); $this->wooCommerceMock = $this->mockWooCommerceClass(WooCommerce::class, []); $this->wooCommerceCartMock = $this->mockWooCommerceClass(WC_Cart::class, ['is_empty', 'get_cart']); diff --git a/mailpoet/tests/integration/Newsletter/Blocks/AbandonedCartContentTest.php b/mailpoet/tests/integration/Newsletter/Blocks/AbandonedCartContentTest.php index 7aceba3c09..38dfbf73c3 100644 --- a/mailpoet/tests/integration/Newsletter/Blocks/AbandonedCartContentTest.php +++ b/mailpoet/tests/integration/Newsletter/Blocks/AbandonedCartContentTest.php @@ -8,7 +8,6 @@ use MailPoet\Entities\NewsletterEntity; use MailPoet\Entities\NewsletterOptionEntity; use MailPoet\Entities\NewsletterOptionFieldEntity; use MailPoet\Entities\NewsletterPostEntity; -use MailPoet\Models\Newsletter; use MailPoet\Newsletter\NewslettersRepository; use MailPoet\Newsletter\Scheduler\AutomaticEmailScheduler; use MailPoet\WP\Functions as WPFunctions; @@ -198,8 +197,7 @@ class AbandonedCartContentTest extends \MailPoetTest { private function createSendingTask($newsletter, $subscriberId = null, $meta = null) { $subscriberId = $subscriberId ?: 1; // dummy default value $meta = $meta ?: [AbandonedCart::TASK_META_NAME => array_slice($this->productIds, 0, 3)]; - $sendingTask = $this->automaticEmailScheduler - ->createAutomaticEmailSendingTask(Newsletter::findOne($newsletter->getId()), $subscriberId, $meta); + $sendingTask = $this->automaticEmailScheduler->createAutomaticEmailSendingTask($newsletter, $subscriberId, $meta); return $sendingTask; } diff --git a/mailpoet/tests/integration/Newsletter/Scheduler/AutomaticEmailTest.php b/mailpoet/tests/integration/Newsletter/Scheduler/AutomaticEmailTest.php index da7e8a64b1..9ab2d2f3c3 100644 --- a/mailpoet/tests/integration/Newsletter/Scheduler/AutomaticEmailTest.php +++ b/mailpoet/tests/integration/Newsletter/Scheduler/AutomaticEmailTest.php @@ -3,6 +3,8 @@ namespace MailPoet\Newsletter\Scheduler; use Codeception\Util\Fixtures; +use MailPoet\Entities\NewsletterEntity; +use MailPoet\Entities\NewsletterOptionFieldEntity; use MailPoet\Entities\NewsletterPostEntity; use MailPoet\Models\Newsletter; use MailPoet\Models\NewsletterOption; @@ -11,6 +13,7 @@ use MailPoet\Models\ScheduledTask; use MailPoet\Models\ScheduledTaskSubscriber; use MailPoet\Models\SendingQueue; use MailPoet\Models\Subscriber; +use MailPoet\Newsletter\NewslettersRepository; use MailPoet\Tasks\Sending as SendingTask; use MailPoet\WP\Functions as WPFunctions; use MailPoetVendor\Carbon\Carbon; @@ -21,9 +24,13 @@ class AutomaticEmailTest extends \MailPoetTest { /** @var AutomaticEmailScheduler */ private $automaticEmailScheduler; + /** @var NewslettersRepository */ + private $newslettersRepository; + public function _before() { parent::_before(); $this->automaticEmailScheduler = $this->diContainer->get(AutomaticEmailScheduler::class); + $this->newslettersRepository = $this->diContainer->get(NewslettersRepository::class); } public function testItCreatesScheduledAutomaticEmailSendingTaskForUser() { @@ -36,15 +43,15 @@ class AutomaticEmailTest extends \MailPoetTest { 'afterTimeNumber' => 2, ] ); - $newsletter = Newsletter::filter('filterWithOptions', Newsletter::TYPE_AUTOMATIC)->findOne($newsletter->id); - assert($newsletter instanceof Newsletter); + $newsletter = $this->newslettersRepository->findOneById($newsletter->id); + $this->assertInstanceOf(NewsletterEntity::class, $newsletter); $subscriber = Subscriber::create(); $subscriber->hydrate(Fixtures::get('subscriber_template')); $subscriber->save(); $this->automaticEmailScheduler->createAutomaticEmailSendingTask($newsletter, $subscriber->id, $meta = null); // new scheduled task should be created - $task = SendingTask::getByNewsletterId($newsletter->id); + $task = SendingTask::getByNewsletterId($newsletter->getId()); $currentTime = Carbon::createFromTimestamp(WPFunctions::get()->currentTime('timestamp')); Carbon::setTestNow($currentTime); // mock carbon to return current time expect($task->id)->greaterOrEquals(1); @@ -68,8 +75,8 @@ class AutomaticEmailTest extends \MailPoetTest { 'afterTimeNumber' => 2, ] ); - $newsletter = Newsletter::filter('filterWithOptions', Newsletter::TYPE_AUTOMATIC)->findOne($newsletter->id); - assert($newsletter instanceof Newsletter); + $newsletter = $this->newslettersRepository->findOneById($newsletter->id); + $this->assertInstanceOf(NewsletterEntity::class, $newsletter); $subscriber = Subscriber::create(); $subscriber->hydrate(Fixtures::get('subscriber_template')); $subscriber->save(); @@ -77,7 +84,7 @@ class AutomaticEmailTest extends \MailPoetTest { $this->automaticEmailScheduler->createAutomaticEmailSendingTask($newsletter, $subscriber->id, $meta); // new queue record should be created with meta data - $queue = SendingQueue::where('newsletter_id', $newsletter->id)->findOne(); + $queue = SendingQueue::where('newsletter_id', $newsletter->getId())->findOne(); assert($queue instanceof SendingQueue); expect($queue->getMeta())->equals($meta); } @@ -92,12 +99,12 @@ class AutomaticEmailTest extends \MailPoetTest { 'afterTimeNumber' => 2, ] ); - $newsletter = Newsletter::filter('filterWithOptions', Newsletter::TYPE_AUTOMATIC)->findOne($newsletter->id); - assert($newsletter instanceof Newsletter); + $newsletter = $this->newslettersRepository->findOneById($newsletter->id); + $this->assertInstanceOf(NewsletterEntity::class, $newsletter); $this->automaticEmailScheduler->createAutomaticEmailSendingTask($newsletter, $subscriber = null, $meta = null); // new scheduled task should be created - $task = SendingTask::getByNewsletterId($newsletter->id); + $task = SendingTask::getByNewsletterId($newsletter->getId()); $currentTime = Carbon::createFromTimestamp(WPFunctions::get()->currentTime('timestamp')); Carbon::setTestNow($currentTime); // mock carbon to return current time expect($task->id)->greaterOrEquals(1); @@ -170,15 +177,15 @@ class AutomaticEmailTest extends \MailPoetTest { 'afterTimeNumber' => 2, ] ); - $condition = function($email) { - return $email->sendTo === 'segment'; + $condition = function(NewsletterEntity $email) { + return $email->getOptionValue(NewsletterOptionFieldEntity::NAME_SEND_TO) === 'segment'; }; $wpMock = $this->createMock(WPFunctions::class); $wpMock->expects($this->any()) ->method('currentTime') ->willReturn($currentTime->getTimestamp()); - $automaticEmailScheduler = new AutomaticEmailScheduler(new Scheduler($wpMock)); + $automaticEmailScheduler = new AutomaticEmailScheduler(new Scheduler($wpMock, $this->diContainer->get(NewslettersRepository::class))); // email should only be scheduled if it matches condition ("send to segment") $automaticEmailScheduler->scheduleAutomaticEmail('some_group', 'some_event', $condition); $result = SendingQueue::findMany(); diff --git a/mailpoet/tests/integration/Newsletter/Scheduler/SchedulerTest.php b/mailpoet/tests/integration/Newsletter/Scheduler/SchedulerTest.php index ac9b0856bc..638b6b9b73 100644 --- a/mailpoet/tests/integration/Newsletter/Scheduler/SchedulerTest.php +++ b/mailpoet/tests/integration/Newsletter/Scheduler/SchedulerTest.php @@ -2,18 +2,20 @@ namespace MailPoet\Test\Newsletter\Scheduler; +use MailPoet\Entities\NewsletterEntity; +use MailPoet\Entities\NewsletterOptionEntity; +use MailPoet\Entities\NewsletterOptionFieldEntity; use MailPoet\Entities\NewsletterPostEntity; +use MailPoet\Entities\ScheduledTaskEntity; +use MailPoet\Entities\ScheduledTaskSubscriberEntity; +use MailPoet\Entities\SendingQueueEntity; +use MailPoet\Entities\SubscriberEntity; use MailPoet\Models\Newsletter; use MailPoet\Models\NewsletterOption; use MailPoet\Models\NewsletterOptionField; -use MailPoet\Models\ScheduledTask; -use MailPoet\Models\ScheduledTaskSubscriber; -use MailPoet\Models\SendingQueue; -use MailPoet\Models\Subscriber; use MailPoet\Newsletter\Scheduler\Scheduler; use MailPoet\WP\Functions as WPFunctions; use MailPoetVendor\Carbon\Carbon; -use MailPoetVendor\Idiorm\ORM; class SchedulerTest extends \MailPoetTest { @@ -26,26 +28,26 @@ class SchedulerTest extends \MailPoetTest { } public function testItGetsActiveNewslettersFilteredByTypeAndGroup() { - $this->_createNewsletter($type = Newsletter::TYPE_WELCOME); + $this->_createNewsletter(NewsletterEntity::TYPE_WELCOME); // no newsletters with type "notification" should be found - expect($this->testee->getNewsletters(Newsletter::TYPE_NOTIFICATION))->isEmpty(); + expect($this->testee->getNewsletters(NewsletterEntity::TYPE_NOTIFICATION))->isEmpty(); // one newsletter with type "welcome" should be found - expect($this->testee->getNewsletters(Newsletter::TYPE_WELCOME))->count(1); + expect($this->testee->getNewsletters(NewsletterEntity::TYPE_WELCOME))->count(1); // one automatic email belonging to "test" group should be found - $newsletter = $this->_createNewsletter($type = Newsletter::TYPE_AUTOMATIC); + $newsletter = $this->_createNewsletter(NewsletterEntity::TYPE_AUTOMATIC); $this->_createNewsletterOptions( $newsletter->id, - Newsletter::TYPE_AUTOMATIC, + NewsletterEntity::TYPE_AUTOMATIC, [ - 'group' => 'test', + NewsletterOptionFieldEntity::NAME_GROUP => 'test', ] ); - expect($this->testee->getNewsletters(Newsletter::TYPE_AUTOMATIC, 'group_does_not_exist'))->isEmpty(); - expect($this->testee->getNewsletters(Newsletter::TYPE_WELCOME, 'test'))->count(1); + expect($this->testee->getNewsletters(Newsletter::TYPE_WELCOME, 'group_does_not_exist'))->isEmpty(); + expect($this->testee->getNewsletters(Newsletter::TYPE_AUTOMATIC, 'test'))->count(1); } public function testItCanGetNextRunDate() { @@ -107,13 +109,13 @@ class SchedulerTest extends \MailPoetTest { public function _after() { Carbon::setTestNow(); - ORM::raw_execute('TRUNCATE ' . Newsletter::$_table); - ORM::raw_execute('TRUNCATE ' . NewsletterOption::$_table); - ORM::raw_execute('TRUNCATE ' . NewsletterOptionField::$_table); + $this->truncateEntity(NewsletterEntity::class); + $this->truncateEntity(NewsletterOptionEntity::class); + $this->truncateEntity(NewsletterOptionFieldEntity::class); $this->truncateEntity(NewsletterPostEntity::class); - ORM::raw_execute('TRUNCATE ' . ScheduledTask::$_table); - ORM::raw_execute('TRUNCATE ' . ScheduledTaskSubscriber::$_table); - ORM::raw_execute('TRUNCATE ' . SendingQueue::$_table); - ORM::raw_execute('TRUNCATE ' . Subscriber::$_table); + $this->truncateEntity(ScheduledTaskEntity::class); + $this->truncateEntity(ScheduledTaskSubscriberEntity::class); + $this->truncateEntity(SendingQueueEntity::class); + $this->truncateEntity(SubscriberEntity::class); } } diff --git a/mailpoet/tests/integration/Newsletter/Scheduler/WelcomeTest.php b/mailpoet/tests/integration/Newsletter/Scheduler/WelcomeTest.php index 8d3f15bd51..7cfac8ce18 100644 --- a/mailpoet/tests/integration/Newsletter/Scheduler/WelcomeTest.php +++ b/mailpoet/tests/integration/Newsletter/Scheduler/WelcomeTest.php @@ -467,7 +467,7 @@ class WelcomeTest extends \MailPoetTest { $this->segmentRepository, $this->diContainer->get(NewslettersRepository::class), $this->diContainer->get(ScheduledTasksRepository::class), - new Scheduler($wpMock) + new Scheduler($wpMock, $this->diContainer->get(NewslettersRepository::class)) ); } diff --git a/mailpoet/tests/unit/Newsletter/Scheduler/SchedulerTest.php b/mailpoet/tests/unit/Newsletter/Scheduler/SchedulerTest.php index 3fcfbeabf1..cb639bc0c7 100644 --- a/mailpoet/tests/unit/Newsletter/Scheduler/SchedulerTest.php +++ b/mailpoet/tests/unit/Newsletter/Scheduler/SchedulerTest.php @@ -2,6 +2,7 @@ namespace MailPoet\Test\Newsletter\Editor; +use MailPoet\Newsletter\NewslettersRepository; use MailPoet\Newsletter\Scheduler\Scheduler; use MailPoet\WP\Functions as WPFunctions; use MailPoetVendor\Carbon\Carbon; @@ -24,7 +25,8 @@ class SchedulerTest extends \MailPoetUnitTest { $wp = $this->makeEmpty(WPFunctions::class, [ 'currentTime' => $this->currentTime->getTimestamp(), ]); - $this->testee = new Scheduler($wp); + $newslettersRepository = $this->makeEmpty(NewslettersRepository::class); + $this->testee = new Scheduler($wp, $newslettersRepository); } public function testItScheduleTimeWithDelayByHours(): void {