diff --git a/lib/API/JSON/v1/Subscribers.php b/lib/API/JSON/v1/Subscribers.php index be5f21aafc..fd52e6b89e 100644 --- a/lib/API/JSON/v1/Subscribers.php +++ b/lib/API/JSON/v1/Subscribers.php @@ -7,7 +7,6 @@ use MailPoet\API\JSON\Error as APIError; use MailPoet\API\JSON\Response as APIResponse; use MailPoet\API\JSON\ResponseBuilders\SubscribersResponseBuilder; use MailPoet\Config\AccessControl; -use MailPoet\DynamicSegments\FreePluginConnectors\AddToSubscribersFilters; use MailPoet\Entities\StatisticsUnsubscribeEntity; use MailPoet\Entities\SubscriberEntity; use MailPoet\Form\Util\FieldNameObfuscator; @@ -87,9 +86,6 @@ class Subscribers extends APIEndpoint { /** @var SubscriberListingRepository */ private $subscriberListingRepository; - /** @var AddToSubscribersFilters */ - private $dynamicSegmentsFiltersLoader; - public function __construct( Listing\BulkActionController $bulkActionController, SubscriberActions $subscriberActions, @@ -105,8 +101,7 @@ class Subscribers extends APIEndpoint { SubscribersRepository $subscribersRepository, SubscribersResponseBuilder $subscribersResponseBuilder, SubscriberListingRepository $subscriberListingRepository, - FieldNameObfuscator $fieldNameObfuscator, - AddToSubscribersFilters $dynamicSegmentsFiltersLoader + FieldNameObfuscator $fieldNameObfuscator ) { $this->bulkActionController = $bulkActionController; $this->subscriberActions = $subscriberActions; @@ -123,7 +118,6 @@ class Subscribers extends APIEndpoint { $this->subscribersRepository = $subscribersRepository; $this->subscribersResponseBuilder = $subscribersResponseBuilder; $this->subscriberListingRepository = $subscriberListingRepository; - $this->dynamicSegmentsFiltersLoader = $dynamicSegmentsFiltersLoader; } public function get($data = []) { @@ -143,7 +137,6 @@ class Subscribers extends APIEndpoint { $count = $this->subscriberListingRepository->getCount($definition); $filters = $this->subscriberListingRepository->getFilters($definition); $groups = $this->subscriberListingRepository->getGroups($definition); - $filters['segment'] = $this->dynamicSegmentsFiltersLoader->add($filters['segment'] ?? []); $subscribers = $this->subscribersResponseBuilder->buildForListing($items); if ($data['filter']['segment'] ?? false) { foreach ($subscribers as $key => $subscriber) { diff --git a/lib/Subscribers/SubscriberListingRepository.php b/lib/Subscribers/SubscriberListingRepository.php index 985094c29d..a4860f31b5 100644 --- a/lib/Subscribers/SubscriberListingRepository.php +++ b/lib/Subscribers/SubscriberListingRepository.php @@ -7,6 +7,7 @@ use MailPoet\Entities\SubscriberEntity; use MailPoet\Listing\ListingDefinition; use MailPoet\Listing\ListingRepository; use MailPoet\Segments\DynamicSegments\FilterHandler; +use MailPoet\Segments\SegmentSubscribersRepository; use MailPoet\Util\Helpers; use MailPoet\WP\Functions as WPFunctions; use MailPoetVendor\Doctrine\DBAL\Driver\Statement; @@ -33,10 +34,18 @@ class SubscriberListingRepository extends ListingRepository { /** @var EntityManager */ private $entityManager; - public function __construct(EntityManager $entityManager, FilterHandler $dynamicSegmentsFilter) { + /** @var SegmentSubscribersRepository */ + private $segmentSubscribersRepository; + + public function __construct( + EntityManager $entityManager, + FilterHandler $dynamicSegmentsFilter, + SegmentSubscribersRepository $segmentSubscribersRepository + ) { parent::__construct($entityManager); $this->dynamicSegmentsFilter = $dynamicSegmentsFilter; $this->entityManager = $entityManager; + $this->segmentSubscribersRepository = $segmentSubscribersRepository; } protected function applySelectClause(QueryBuilder $queryBuilder) { @@ -201,28 +210,51 @@ class SubscriberListingRepository extends ListingRepository { ->groupBy('sg.id') ->andWhere('sg.deletedAt IS NULL') ->andWhere('s.deletedAt IS NULL') - ->orderBy('sg.name') ->having('subscribersCount > 0'); // format segment list - $segmentList = [ - [ - 'label' => WPFunctions::get()->__('All Lists', 'mailpoet'), - 'value' => '', - ], + $allSubscribersList = [ + 'label' => WPFunctions::get()->__('All Lists', 'mailpoet'), + 'value' => '', ]; - $segmentList[] = [ + $withoutSegmentList = [ 'label' => $subscribersWithoutSegmentLabel, 'value' => 'none', ]; + $segmentList = []; foreach ($queryBuilder->getQuery()->getResult() as $item) { $segmentList[] = [ 'label' => sprintf('%s (%s)', $item['name'], number_format((float)$item['subscribersCount'])), 'value' => $item['id'], ]; } + + $queryBuilder = clone $this->queryBuilder; + // Load dynamic segments with some subscribers + $queryBuilder + ->select('s') + ->from(SegmentEntity::class, 's') + ->andWhere('s.type = :dynamicType') + ->andWhere('s.deletedAt IS NULL') + ->setParameter('dynamicType', SegmentEntity::TYPE_DYNAMIC); + + foreach ($queryBuilder->getQuery()->getResult() as $segment) { + $count = $this->segmentSubscribersRepository->getSubscribersCount($segment->getId()); + if (!$count) { + continue; + } + $segmentList[] = [ + 'label' => sprintf('%s (%s)', $segment->getName(), number_format((float)$count)), + 'value' => $segment->getId(), + ]; + } + usort($segmentList, function($a, $b) { + return strcasecmp($a['label'], $b['label']); + }); + + array_unshift($segmentList, $allSubscribersList, $withoutSegmentList); return ['segment' => $segmentList]; } diff --git a/tests/integration/API/JSON/v1/SubscribersTest.php b/tests/integration/API/JSON/v1/SubscribersTest.php index a28a54ea81..ab5b1ec90c 100644 --- a/tests/integration/API/JSON/v1/SubscribersTest.php +++ b/tests/integration/API/JSON/v1/SubscribersTest.php @@ -7,7 +7,6 @@ use MailPoet\API\JSON\Response as APIResponse; use MailPoet\API\JSON\ResponseBuilders\SubscribersResponseBuilder; use MailPoet\API\JSON\v1\Subscribers; use MailPoet\DI\ContainerWrapper; -use MailPoet\DynamicSegments\FreePluginConnectors\AddToSubscribersFilters; use MailPoet\Entities\CustomFieldEntity; use MailPoet\Entities\FormEntity; use MailPoet\Entities\NewsletterEntity; @@ -48,6 +47,8 @@ use MailPoet\WP\Functions; use MailPoetVendor\Carbon\Carbon; use MailPoetVendor\Idiorm\ORM; +require_once(ABSPATH . 'wp-admin/includes/user.php'); + class SubscribersTest extends \MailPoetTest { /** @var FormEntity */ @@ -100,8 +101,7 @@ class SubscribersTest extends \MailPoetTest { $container->get(SubscribersRepository::class), $container->get(SubscribersResponseBuilder::class), $container->get(SubscriberListingRepository::class), - $obfuscator, - $container->get(AddToSubscribersFilters::class) + $obfuscator ); $this->obfuscatedEmail = $obfuscator->obfuscate('email'); $this->obfuscatedSegments = $obfuscator->obfuscate('segments'); @@ -322,15 +322,26 @@ class SubscribersTest extends \MailPoetTest { $dynamicSegmentFactory = new DynamicSegment(); $dynamicSegment = $dynamicSegmentFactory ->withName('Dynamic') - ->withUserRoleFilter('master_of_universe') + ->withUserRoleFilter('editor') ->create(); $dynamicSegment->save(); + $wpUserEmail = 'wpuserEditor@example.com'; + wp_insert_user([ + 'user_login' => 'user-role-test1', + 'user_email' => $wpUserEmail, + 'role' => 'editor', + 'user_pass' => '12123154', + ]); $response = $this->endpoint->listing([ 'filter' => [ 'segment' => $dynamicSegment->id, ], ]); - expect($response->meta['filters']['segment'])->contains(['value' => $dynamicSegment->id, 'label' => 'Dynamic (0)']); + expect($response->meta['filters']['segment'])->contains(['value' => $dynamicSegment->id, 'label' => 'Dynamic (1)']); + $user = get_user_by('email', $wpUserEmail); + if ($user) { + wp_delete_user($user->ID); + } } public function testItCanSearchListing() { diff --git a/tests/integration/Subscribers/SubscriberListingRepositoryTest.php b/tests/integration/Subscribers/SubscriberListingRepositoryTest.php index 242a8b27c9..51196f3c16 100644 --- a/tests/integration/Subscribers/SubscriberListingRepositoryTest.php +++ b/tests/integration/Subscribers/SubscriberListingRepositoryTest.php @@ -8,6 +8,7 @@ use MailPoet\Entities\SubscriberEntity; use MailPoet\Entities\SubscriberSegmentEntity; use MailPoet\Listing\ListingDefinition; use MailPoet\Segments\DynamicSegments\FilterHandler; +use MailPoet\Segments\SegmentSubscribersRepository; require_once(ABSPATH . 'wp-admin/includes/user.php'); @@ -33,7 +34,8 @@ class SubscriberListingRepositoryTest extends \MailPoetTest { public function _before() { $this->repository = new SubscriberListingRepository( $this->entityManager, - $this->diContainer->get(FilterHandler::class) + $this->diContainer->get(FilterHandler::class), + $this->diContainer->get(SegmentSubscribersRepository::class) ); $this->cleanup(); } @@ -166,10 +168,12 @@ class SubscriberListingRepositoryTest extends \MailPoetTest { $this->entityManager->flush(); $this->listingData['filter'] = ['segment' => $list->getId()]; + $this->listingData['sort_by'] = 'id'; $data = $this->repository->getData($this->getListingDefinition()); expect(count($data))->equals(2); expect($data[0]->getEmail())->equals($subscriberUnsubscribedFromAList->getEmail()); expect($data[1]->getEmail())->equals($regularSubscriber->getEmail()); + $this->listingData['sort_by'] = ''; } public function testLoadSubscribersInDynamicSegment() {