Skip to content

Commit 6a90de2

Browse files
committed
Subscriber filter in get subscribers endpoint
1 parent f49ce4e commit 6a90de2

5 files changed

Lines changed: 186 additions & 7 deletions

File tree

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,11 @@ contribute and how to run the unit tests and style checks locally.
6060
This project adheres to a [Contributor Code of Conduct](CODE_OF_CONDUCT.md).
6161
By participating in this project and its community, you are expected to uphold
6262
this code.
63+
64+
65+
### Code style checks
66+
```bash
67+
vendor/bin/phpstan analyse -l 5 src/ tests/
68+
vendor/bin/phpmd src/ text vendor/phplist/core/config/PHPMD/rules.xml
69+
vendor/bin/phpcs --standard=vendor/phplist/core/config/PhpCodeSniffer/ src/ tests/
70+
```

src/Subscription/Controller/SubscriberController.php

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
use Doctrine\ORM\EntityManagerInterface;
88
use OpenApi\Attributes as OA;
99
use PhpList\Core\Domain\Identity\Model\PrivilegeFlag;
10-
use PhpList\Core\Domain\Subscription\Model\Filter\SubscriberFilter;
1110
use PhpList\Core\Domain\Subscription\Model\Subscriber;
1211
use PhpList\Core\Domain\Subscription\Service\Manager\SubscriberManager;
1312
use PhpList\Core\Security\Authentication;
1413
use PhpList\RestBundle\Common\Controller\BaseController;
1514
use PhpList\RestBundle\Common\Validator\RequestValidator;
1615
use PhpList\RestBundle\Common\Service\Provider\PaginatedDataProvider;
1716
use PhpList\RestBundle\Subscription\Request\CreateSubscriberRequest;
17+
use PhpList\RestBundle\Subscription\Request\SubscribersFilterRequest;
1818
use PhpList\RestBundle\Subscription\Request\UpdateSubscriberRequest;
1919
use PhpList\RestBundle\Subscription\Serializer\SubscriberNormalizer;
2020
use PhpList\RestBundle\Subscription\Service\SubscriberHistoryService;
@@ -104,14 +104,17 @@ public function getSubscribers(Request $request): JsonResponse
104104
{
105105
$this->requireAuthentication($request);
106106

107+
/** @var SubscribersFilterRequest $subscriberRequest */
108+
$subscriberRequest = $this->validator->validate($request, SubscribersFilterRequest::class);
109+
107110
return $this->json(
108-
$this->paginatedDataProvider->getPaginatedList(
109-
$request,
110-
$this->subscriberNormalizer,
111-
Subscriber::class,
112-
new SubscriberFilter(),
111+
data: $this->paginatedDataProvider->getPaginatedList(
112+
request: $request,
113+
normalizer: $this->subscriberNormalizer,
114+
className: Subscriber::class,
115+
filter: $subscriberRequest->getDto(),
113116
),
114-
Response::HTTP_OK
117+
status: Response::HTTP_OK
115118
);
116119
}
117120

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Subscription\Request;
6+
7+
use OpenApi\Attributes as OA;
8+
use PhpList\Core\Domain\Subscription\Model\Filter\SubscriberFilter;
9+
use PhpList\RestBundle\Common\Request\RequestInterface;
10+
use Symfony\Component\Validator\Constraints as Assert;
11+
12+
#[OA\Schema(
13+
schema: 'SubscribersFilterRequest',
14+
properties: [
15+
new OA\Property(
16+
property: 'is_confirmed',
17+
description: 'Filter by confirmed status',
18+
type: 'boolean',
19+
nullable: true
20+
),
21+
new OA\Property(
22+
property: 'is_blacklisted',
23+
description: 'Filter by blacklisted status',
24+
type: 'boolean',
25+
nullable: true
26+
),
27+
new OA\Property(
28+
property: 'sort_by',
29+
description: 'Column to sort by',
30+
type: 'string',
31+
nullable: true
32+
),
33+
new OA\Property(
34+
property: 'sort_direction',
35+
description: 'Sort direction',
36+
type: 'string',
37+
enum: ['asc', 'desc'],
38+
nullable: true
39+
),
40+
new OA\Property(
41+
property: 'find_column',
42+
description: 'Column to search in (requires find_value)',
43+
type: 'string',
44+
nullable: true
45+
),
46+
new OA\Property(
47+
property: 'find_value',
48+
description: 'Value to search for (requires find_column)',
49+
type: 'string',
50+
nullable: true
51+
),
52+
],
53+
type: 'object'
54+
)]
55+
class SubscribersFilterRequest implements RequestInterface
56+
{
57+
#[Assert\Type(type: 'boolean')]
58+
public ?bool $isConfirmed = null;
59+
60+
#[Assert\Type(type: 'boolean')]
61+
public ?bool $isBlacklisted = null;
62+
63+
#[Assert\Type(type: 'string')]
64+
public ?string $sortBy = null;
65+
66+
#[Assert\Choice(choices: ['asc', 'desc'])]
67+
public ?string $sortDirection = null;
68+
69+
#[Assert\Type(type: 'string')]
70+
public ?string $findColumn = null;
71+
72+
#[Assert\Type(type: 'string')]
73+
public ?string $findValue = null;
74+
75+
public function getDto(): SubscriberFilter
76+
{
77+
$findColumn = $this->findColumn;
78+
$findValue = $this->findValue;
79+
if (($findColumn === null) xor ($findValue === null)) {
80+
$findColumn = null;
81+
$findValue = null;
82+
}
83+
84+
return new SubscriberFilter(
85+
isConfirmed: $this->isConfirmed,
86+
isBlacklisted: $this->isBlacklisted,
87+
sortBy: $this->sortBy,
88+
sortDirection: $this->sortDirection,
89+
findColumn: $findColumn,
90+
findValue: $findValue,
91+
);
92+
}
93+
}

tests/Integration/Subscription/Controller/SubscriberControllerTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* Testcase.
1616
*
1717
* @author Oliver Klee <oliver@phplist.com>
18+
* @author Tatevik Grigoryan <tatevik@phplist.com>
1819
*/
1920
class SubscriberControllerTest extends AbstractTestController
2021
{
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpList\RestBundle\Tests\Unit\Subscription\Request;
6+
7+
use PhpList\Core\Domain\Subscription\Model\Filter\SubscriberFilter;
8+
use PhpList\RestBundle\Subscription\Request\SubscribersFilterRequest;
9+
use PHPUnit\Framework\TestCase;
10+
11+
class SubscribersFilterRequestTest extends TestCase
12+
{
13+
public function testGetDtoReturnsCorrectDtoWithAllValues(): void
14+
{
15+
$request = new SubscribersFilterRequest();
16+
$request->isConfirmed = true;
17+
$request->isBlacklisted = false;
18+
$request->sortBy = 'email';
19+
$request->sortDirection = 'desc';
20+
$request->findColumn = 'email';
21+
$request->findValue = 'test@example.com';
22+
23+
$dto = $request->getDto();
24+
25+
$this->assertInstanceOf(SubscriberFilter::class, $dto);
26+
$this->assertTrue($dto->getIsConfirmed());
27+
$this->assertFalse($dto->getIsBlacklisted());
28+
$this->assertEquals('email', $dto->getSortBy());
29+
$this->assertEquals('desc', $dto->getSortDirection());
30+
$this->assertEquals('email', $dto->getFindColumn());
31+
$this->assertEquals('test@example.com', $dto->getFindValue());
32+
}
33+
34+
public function testGetDtoReturnsCorrectDtoWithNullValues(): void
35+
{
36+
$request = new SubscribersFilterRequest();
37+
38+
$dto = $request->getDto();
39+
40+
$this->assertInstanceOf(SubscriberFilter::class, $dto);
41+
$this->assertNull($dto->getIsConfirmed());
42+
$this->assertNull($dto->getIsBlacklisted());
43+
$this->assertNull($dto->getSortBy());
44+
$this->assertNull($dto->getSortDirection());
45+
$this->assertNull($dto->getFindColumn());
46+
$this->assertNull($dto->getFindValue());
47+
}
48+
49+
public function testGetDtoNulsFindColumnAndValueWhenOnlyColumnProvided(): void
50+
{
51+
$request = new SubscribersFilterRequest();
52+
$request->findColumn = 'email';
53+
$request->findValue = null;
54+
55+
$dto = $request->getDto();
56+
57+
$this->assertInstanceOf(SubscriberFilter::class, $dto);
58+
$this->assertNull($dto->getFindColumn());
59+
$this->assertNull($dto->getFindValue());
60+
}
61+
62+
public function testGetDtoNulsFindColumnAndValueWhenOnlyValueProvided(): void
63+
{
64+
$request = new SubscribersFilterRequest();
65+
$request->findColumn = null;
66+
$request->findValue = 'test@example.com';
67+
68+
$dto = $request->getDto();
69+
70+
$this->assertInstanceOf(SubscriberFilter::class, $dto);
71+
$this->assertNull($dto->getFindColumn());
72+
$this->assertNull($dto->getFindValue());
73+
}
74+
}

0 commit comments

Comments
 (0)