Skip to content
This repository was archived by the owner on Apr 3, 2023. It is now read-only.

Commit dce2d41

Browse files
author
Teddy Roncin
committed
✨ (Get users collection) Added an advanced search for route GET /users/
Added many filters for the /users routes. User's nickname are now returned when fetching a collection of users
1 parent 7c7de59 commit dce2d41

File tree

5 files changed

+149
-1
lines changed

5 files changed

+149
-1
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace App\ApiPlatform;
4+
5+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
6+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
7+
use Doctrine\ORM\QueryBuilder;
8+
9+
class IsStudentFilter extends AbstractContextAwareFilter
10+
{
11+
protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
12+
{
13+
if ($property !== 'is_student') {
14+
return;
15+
}
16+
$alias = $queryBuilder->getRootAliases()[0];
17+
$queryBuilder->andWhere("{$alias}.studentId ".($value == 'true' ? 'IS NOT' : 'IS').' NULL');
18+
}
19+
20+
public function getDescription(string $resourceClass): array
21+
{
22+
return [
23+
'is_student' => [
24+
'property' => 'studentId',
25+
'type' => 'bool',
26+
'required' => false,
27+
],
28+
];
29+
}
30+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace App\ApiPlatform;
4+
5+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
6+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
7+
use Doctrine\ORM\QueryBuilder;
8+
9+
class SearchInNamesFilter extends AbstractContextAwareFilter
10+
{
11+
protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
12+
{
13+
if ($property !== 'name') {
14+
return;
15+
}
16+
$alias = $queryBuilder->getRootAliases()[0];
17+
$infoAlias = $queryNameGenerator->generateJoinAlias('info');
18+
$queryBuilder
19+
->innerJoin("{$alias}.infos", $infoAlias)
20+
->andWhere("({$alias}.firstName LIKE '%{$value}%' OR {$alias}.lastName LIKE '%{$value}%' OR {$infoAlias}.nickname LIKE '%{$value}%')");
21+
}
22+
23+
public function getDescription(string $resourceClass): array
24+
{
25+
return [
26+
'name' => [
27+
'property' => 'name',
28+
'type' => 'string',
29+
'required' => false,
30+
],
31+
];
32+
}
33+
}

src/ApiPlatform/UEFilter.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace App\ApiPlatform;
4+
5+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
6+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
7+
use App\Repository\SemesterRepository;
8+
use Doctrine\ORM\QueryBuilder;
9+
use Symfony\Component\PropertyInfo\Type;
10+
11+
class UEFilter extends AbstractContextAwareFilter
12+
{
13+
14+
protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
15+
{
16+
if ($property !== 'ue') {
17+
return;
18+
}
19+
$alias = $queryBuilder->getRootAliases()[0];
20+
foreach ($value as $ueCode) {
21+
$ueAlias = $queryNameGenerator->generateJoinAlias('UE');
22+
$ueSubscriptionAlias = $queryNameGenerator->generateJoinAlias('UEsSubscriptions');
23+
$semesterAlias = $queryNameGenerator->generateJoinAlias('Semester');
24+
$queryBuilder->innerJoin("{$alias}.UEsSubscriptions", $ueSubscriptionAlias)
25+
->innerJoin("${ueSubscriptionAlias}.UE", $ueAlias)
26+
->innerJoin("${ueSubscriptionAlias}.semester", $semesterAlias)
27+
->andWhere("{$ueAlias}.code = '{$ueCode}'")
28+
->andWhere("{$semesterAlias}.start <= :now")
29+
->andWhere("{$semesterAlias}.end >= :now");
30+
}
31+
$queryBuilder->setParameter('now', new \DateTime());
32+
}
33+
34+
public function getDescription(string $resourceClass): array
35+
{
36+
return [
37+
'ue[]' => [
38+
'property' => 'ue',
39+
'type' => 'array',
40+
'required' => false,
41+
'is_collection' => true,
42+
],
43+
];
44+
}
45+
}

src/Entity/User.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22

33
namespace App\Entity;
44

5+
use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
6+
use ApiPlatform\Metadata\ApiFilter;
57
use ApiPlatform\Metadata\ApiResource;
68
use ApiPlatform\Metadata\Delete;
79
use ApiPlatform\Metadata\Get;
810
use ApiPlatform\Metadata\GetCollection;
911
use ApiPlatform\Metadata\Patch;
12+
use App\ApiPlatform\IsStudentFilter;
13+
use App\ApiPlatform\SearchInNamesFilter;
14+
use App\ApiPlatform\UEFilter;
1015
use App\Controller\GetEDTController;
1116
use App\Controller\SoftDeleteController;
1217
use App\DataProvider\UserDataVisibilityItemDataProvider;
@@ -24,6 +29,7 @@
2429
* The main entity that represents all Users. It is related to UEs, Covoits, Assos and others.
2530
*
2631
* @ORM\Entity(repositoryClass=UserRepository::class)
32+
*
2733
* @ORM\Table(name="users")
2834
*/
2935
#[
@@ -58,15 +64,33 @@
5864
],
5965
paginationItemsPerPage: 10,
6066
security: "is_granted('ROLE_USER')",
61-
)
67+
),
68+
ApiFilter(
69+
SearchFilter::class,
70+
properties: [
71+
'studentId' => 'exact',
72+
'mailsPhones.mailPersonal' => 'exact',
73+
'mailsPhones.phoneNumber' => 'exact',
74+
'branche.branche.code' => 'exact',
75+
'branche.filiere.code' => 'exact',
76+
'branche.semesterNumber' => 'exact',
77+
]
78+
),
79+
ApiFilter(UEFilter::class),
80+
ApiFilter(SearchInNamesFilter::class),
81+
ApiFilter(IsStudentFilter::class),
6282
]
6383
class User implements UserInterface
6484
{
6585
/**
6686
* @ORM\Id
87+
*
6788
* @ORM\Column(type="uuid", unique=true)
89+
*
6890
* @ORM\GeneratedValue(strategy="CUSTOM")
91+
*
6992
* @ORM\CustomIdGenerator(class=UuidGenerator::class)
93+
*
7094
* @Assert\Uuid()
7195
*/
7296
#[Groups([
@@ -79,8 +103,11 @@ class User implements UserInterface
79103
* The CAS login of the User.
80104
*
81105
* @ORM\Column(type="string", length=50, unique=true)
106+
*
82107
* @Assert\Type("string")
108+
*
83109
* @Assert\Length(max=50)
110+
*
84111
* @Assert\Regex("/^[a-z_0-9]{1,50}$/")
85112
*/
86113
#[Groups([
@@ -93,7 +120,9 @@ class User implements UserInterface
93120
* For the User that are students, this is the UTT student number.
94121
*
95122
* @ORM\Column(type="integer", nullable=true, unique=true)
123+
*
96124
* @Assert\Type("int")
125+
*
97126
* @Assert\Positive
98127
*/
99128
#[Groups([
@@ -103,7 +132,9 @@ class User implements UserInterface
103132

104133
/**
105134
* @ORM\Column(type="string", length=255)
135+
*
106136
* @Assert\Type("string")
137+
*
107138
* @Assert\Length(max=255)
108139
*/
109140
#[Groups([
@@ -114,7 +145,9 @@ class User implements UserInterface
114145

115146
/**
116147
* @ORM\Column(type="string", length=255)
148+
*
117149
* @Assert\Type("string")
150+
*
118151
* @Assert\Length(max=255)
119152
*/
120153
#[Groups([
@@ -141,6 +174,7 @@ class User implements UserInterface
141174
* The relation to the entity that contains the User's SocialNetwork.
142175
*
143176
* @ORM\OneToOne(targetEntity=UserSocialNetwork::class, mappedBy="user", cascade={"persist", "remove"})
177+
*
144178
* @Assert\Valid()
145179
*/
146180
#[Groups([
@@ -160,6 +194,7 @@ class User implements UserInterface
160194
* The relation to the entity that contains the User's RGPD.
161195
*
162196
* @ORM\OneToOne(targetEntity=UserRGPD::class, mappedBy="user", cascade={"persist", "remove"})
197+
*
163198
* @Assert\Valid()
164199
*/
165200
#[Groups([
@@ -244,6 +279,7 @@ class User implements UserInterface
244279
* The relation to the Preference of the User.
245280
*
246281
* @ORM\OneToOne(targetEntity=UserPreference::class, mappedBy="user", cascade={"persist", "remove"})
282+
*
247283
* @Assert\Valid()
248284
*/
249285
#[Groups([
@@ -256,6 +292,7 @@ class User implements UserInterface
256292
* The relation to the Infos of the User.
257293
*
258294
* @ORM\OneToOne(targetEntity=UserInfos::class, mappedBy="user", cascade={"persist", "remove"})
295+
*
259296
* @Assert\Valid()
260297
*/
261298
#[Groups([
@@ -269,6 +306,7 @@ class User implements UserInterface
269306
* The relation to the Addresses of the User.
270307
*
271308
* @ORM\OneToMany(targetEntity=UserAddress::class, mappedBy="user", cascade={"persist", "remove"}, orphanRemoval=true)
309+
*
272310
* @Assert\Valid()
273311
*/
274312
#[Groups([
@@ -281,6 +319,7 @@ class User implements UserInterface
281319
* The relation to mails and phone number of the User.
282320
*
283321
* @ORM\OneToOne(targetEntity=UserMailsPhones::class, mappedBy="user", cascade={"persist", "remove"})
322+
*
284323
* @Assert\Valid()
285324
*/
286325
#[Groups([

src/Entity/UserInfos.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class UserInfos
125125
*/
126126
#[Groups([
127127
'user:read:one',
128+
'user:read:some',
128129
'user:write:update',
129130
])]
130131
private $nickname;

0 commit comments

Comments
 (0)