diff --git a/mailpoet/lib/Segments/SegmentSubscribersRepository.php b/mailpoet/lib/Segments/SegmentSubscribersRepository.php index 94d5e5f73f..295911d8c0 100644 --- a/mailpoet/lib/Segments/SegmentSubscribersRepository.php +++ b/mailpoet/lib/Segments/SegmentSubscribersRepository.php @@ -9,6 +9,7 @@ use MailPoet\Entities\SubscriberEntity; use MailPoet\Entities\SubscriberSegmentEntity; use MailPoet\InvalidStateException; use MailPoet\NotFoundException; +use MailPoet\Segments\DynamicSegments\Exceptions\InvalidFilterException; use MailPoet\Segments\DynamicSegments\FilterHandler; use MailPoetVendor\Doctrine\DBAL\Connection; use MailPoetVendor\Doctrine\DBAL\Driver\Statement; @@ -420,7 +421,13 @@ class SegmentSubscribersRepository { if (count($filters) === 0) { return $queryBuilder->andWhere('0 = 1'); } elseif ($segment instanceof SegmentEntity) { - $queryBuilder = $this->filterHandler->apply($queryBuilder, $segment); + try { + $queryBuilder = $this->filterHandler->apply($queryBuilder, $segment); + } catch (InvalidFilterException $e) { + // If a segment has an invalid filter, we should simply consider it empty instead of throwing + // an unhandled error. Unhandled errors here can break many admin pages. + $queryBuilder->andWhere('0 = 1'); + } } $subscribersTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName(); $queryBuilder = $queryBuilder->andWhere("$subscribersTable.deleted_at IS NULL"); diff --git a/mailpoet/tests/integration/Segments/SegmentSubscribersRepositoryTest.php b/mailpoet/tests/integration/Segments/SegmentSubscribersRepositoryTest.php index aa19d21eb9..d983760df0 100644 --- a/mailpoet/tests/integration/Segments/SegmentSubscribersRepositoryTest.php +++ b/mailpoet/tests/integration/Segments/SegmentSubscribersRepositoryTest.php @@ -229,6 +229,22 @@ class SegmentSubscribersRepositoryTest extends \MailPoetTest { verify($countWithFilter)->equals(2); } + public function testSubscriberCountIsZeroIfItHasAnInvalidFilter(): void { + $segment = new SegmentEntity('Segment' . rand(0, 10000), SegmentEntity::TYPE_DYNAMIC, 'Segment description'); + $filterData = new DynamicSegmentFilterData( + 'typeThatDefinitelyDoesNotExist', + 'theActionDoesNotExistEither' + ); + $dynamicFilter = new DynamicSegmentFilterEntity($segment, $filterData); + $segment->getDynamicFilters()->add($dynamicFilter); + $this->entityManager->persist($segment); + $this->entityManager->persist($dynamicFilter); + $this->entityManager->flush(); + + $count = $this->repository->getSubscribersCountBySegmentIds([$segment->getId()]); + $this->assertEquals(0, $count); + } + public function _after() { parent::_after(); $this->cleanup();