diff --git a/lib/API/JSON/v1/Subscribers.php b/lib/API/JSON/v1/Subscribers.php index ba90549e6d..385f0a384a 100644 --- a/lib/API/JSON/v1/Subscribers.php +++ b/lib/API/JSON/v1/Subscribers.php @@ -10,7 +10,9 @@ use MailPoet\Form\Util\FieldNameObfuscator; use MailPoet\Models\Form; use MailPoet\Models\StatisticsForms; use MailPoet\Models\Subscriber; +use MailPoet\Segments\SubscribersListings; use MailPoet\Subscription\Throttling as SubscriptionThrottling; +use MailPoet\WP\Hooks; if(!defined('ABSPATH')) exit; @@ -40,12 +42,15 @@ class Subscribers extends APIEndpoint { } function listing($data = array()) { - $listing = new Listing\Handler( - '\MailPoet\Models\Subscriber', - $data - ); - $listing_data = $listing->get(); + if(!isset($data['filter']['segment'])) { + $listing = new Listing\Handler('\MailPoet\Models\Subscriber', $data); + + $listing_data = $listing->get(); + } else { + $listings = new SubscribersListings(); + $listing_data = $listings->getListingsInSegment($data); + } $data = array(); foreach($listing_data['items'] as $subscriber) { diff --git a/lib/Segments/SubscribersListings.php b/lib/Segments/SubscribersListings.php new file mode 100644 index 0000000000..1cf13b1ea8 --- /dev/null +++ b/lib/Segments/SubscribersListings.php @@ -0,0 +1,39 @@ +asArray(); + } + return $this->getListings($segment, $data); + + } + + private function getListings($segment, $data) { + if(!$segment || $segment['type'] === Segment::TYPE_DEFAULT || $segment['type'] === Segment::TYPE_WP_USERS) { + $listing = new Handler('\MailPoet\Models\Subscriber', $data); + + return $listing_data = $listing->get(); + } + $handlers = Hooks::applyFilters('mailpoet_get_subscribers_listings_in_segment_handlers', array()); + foreach($handlers as $handler) { + $listings = $handler->get($segment, $data); + if($listings) { + return $listings; + } + } + throw new \InvalidArgumentException('No handler found for segment'); + } + +} \ No newline at end of file diff --git a/tests/unit/API/JSON/v1/SubscribersTest.php b/tests/unit/API/JSON/v1/SubscribersTest.php index 58a7622f00..6cf8378191 100644 --- a/tests/unit/API/JSON/v1/SubscribersTest.php +++ b/tests/unit/API/JSON/v1/SubscribersTest.php @@ -220,6 +220,20 @@ class SubscribersTest extends \MailPoetTest { expect($response->data[0]['email'])->equals($this->subscriber_2->email); } + function testItCanAddSegmentsUsingHooks() { + $add_segment = function() { + return 'segment'; + }; + add_filter('mailpoet_subscribers_listings_filters_segments', $add_segment); + $router = new Subscribers(); + $response = $router->listing(array( + 'filter' => array( + 'segment' => $this->segment_2->id + ) + )); + expect($response->meta['filters']['segment'])->equals('segment'); + } + function testItCanSearchListing() { $new_subscriber = Subscriber::createOrUpdate(array( 'email' => 'search.me@find.me', diff --git a/tests/unit/Segments/DynamicListingsHandlerMock.php b/tests/unit/Segments/DynamicListingsHandlerMock.php new file mode 100644 index 0000000000..adc7d8a9ba --- /dev/null +++ b/tests/unit/Segments/DynamicListingsHandlerMock.php @@ -0,0 +1,11 @@ +segment_1 = Segment::createOrUpdate(array('name' => 'Segment 1', 'type' => 'default')); + $this->segment_2 = Segment::createOrUpdate(array('name' => 'Segment 3', 'type' => 'not default')); + $this->subscriber_1 = Subscriber::createOrUpdate(array( + 'email' => 'john@mailpoet.com', + 'first_name' => 'John', + 'last_name' => 'Doe', + 'status' => Subscriber::STATUS_SUBSCRIBED, + 'segments' => array( + $this->segment_1->id, + ), + )); + $this->subscriber_2 = Subscriber::createOrUpdate(array( + 'email' => 'jake@mailpoet.com', + 'first_name' => 'Jake', + 'last_name' => 'Doe', + 'status' => Subscriber::STATUS_SUBSCRIBED, + 'segments' => array( + $this->segment_2->id, + ), + )); + SubscriberSegment::resubscribeToAllSegments($this->subscriber_1); + SubscriberSegment::resubscribeToAllSegments($this->subscriber_2); + } + + function testTryToGetListingsWithoutPassingSegment() { + $finder = new SubscribersListings(); + $this->setExpectedException('InvalidArgumentException'); + $finder->getListingsInSegment(array()); + } + + function testGetListingsForDefaultSegment() { + $finder = new SubscribersListings(); + $listings = $finder->getListingsInSegment(array('filter'=> array('segment' => $this->segment_1->id))); + expect($listings['items'])->count(1); + } + + function testGetListingsForNonExistingSegmen() { + $finder = new SubscribersListings(); + $listings = $finder->getListingsInSegment(array('filter'=> array('segment' => 'non-existing-id'))); + expect($listings['items'])->notEmpty(); + } + + function testGetListingsUsingFilter() { + $mock = Stub::makeEmpty('MailPoet\Test\Segments\DynamicListingsHandlerMock', array('get')); + $mock + ->expects($this->once()) + ->method('get') + ->will($this->returnValue('dynamic listings')); + + remove_all_filters('mailpoet_get_subscribers_listings_in_segment_handlers'); + Hooks::addFilter('mailpoet_get_subscribers_listings_in_segment_handlers', function () use ($mock) { + return array($mock); + }); + + $finder = new SubscribersListings(); + $listings = $finder->getListingsInSegment(array('filter'=> array('segment' => $this->segment_2->id))); + expect($listings)->equals('dynamic listings'); + } + + function testTryToGetListingsForSegmentWithout() { + $finder = new SubscribersListings(); + $this->setExpectedException('InvalidArgumentException'); + remove_all_filters('mailpoet_get_subscribers_listings_in_segment_handlers'); + $finder->getListingsInSegment(array('filter'=> array('segment' => $this->segment_2->id))); + } + +}