diff --git a/composer.lock b/composer.lock index 7ad1560..17b5d65 100644 --- a/composer.lock +++ b/composer.lock @@ -1763,16 +1763,16 @@ }, { "name": "friendsofphp/proxy-manager-lts", - "version": "v1.0.13", + "version": "v1.0.14", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/proxy-manager-lts.git", - "reference": "88354616f4cf4f6620910fd035e282173ba453e8" + "reference": "a527c9d9d5348e012bd24482d83a5cd643bcbc9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/proxy-manager-lts/zipball/88354616f4cf4f6620910fd035e282173ba453e8", - "reference": "88354616f4cf4f6620910fd035e282173ba453e8", + "url": "https://api.github.com/repos/FriendsOfPHP/proxy-manager-lts/zipball/a527c9d9d5348e012bd24482d83a5cd643bcbc9e", + "reference": "a527c9d9d5348e012bd24482d83a5cd643bcbc9e", "shasum": "" }, "require": { @@ -1829,7 +1829,7 @@ ], "support": { "issues": "https://github.com/FriendsOfPHP/proxy-manager-lts/issues", - "source": "https://github.com/FriendsOfPHP/proxy-manager-lts/tree/v1.0.13" + "source": "https://github.com/FriendsOfPHP/proxy-manager-lts/tree/v1.0.14" }, "funding": [ { @@ -1841,7 +1841,7 @@ "type": "tidelift" } ], - "time": "2022-10-17T19:48:16+00:00" + "time": "2023-01-30T10:40:19+00:00" }, { "name": "guzzlehttp/promises", @@ -4208,16 +4208,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v6.2.5", + "version": "v6.2.6", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "6abd5658d0f7fea98f882a911bfdb8795d189509" + "reference": "2a6dd148589b9db59717db8b75f8d9fbb2ae714f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6abd5658d0f7fea98f882a911bfdb8795d189509", - "reference": "6abd5658d0f7fea98f882a911bfdb8795d189509", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/2a6dd148589b9db59717db8b75f8d9fbb2ae714f", + "reference": "2a6dd148589b9db59717db8b75f8d9fbb2ae714f", "shasum": "" }, "require": { @@ -4275,7 +4275,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.2.5" + "source": "https://github.com/symfony/dependency-injection/tree/v6.2.6" }, "funding": [ { @@ -4291,7 +4291,7 @@ "type": "tidelift" } ], - "time": "2023-01-23T15:50:11+00:00" + "time": "2023-01-30T15:46:28+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5460,16 +5460,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.2.5", + "version": "v6.2.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "9d081ead9d3432e2e8002178d14c4c9dd4b8ffbf" + "reference": "e8dd1f502bc2b3371d05092aa233b064b03ce7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9d081ead9d3432e2e8002178d14c4c9dd4b8ffbf", - "reference": "9d081ead9d3432e2e8002178d14c4c9dd4b8ffbf", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e8dd1f502bc2b3371d05092aa233b064b03ce7ed", + "reference": "e8dd1f502bc2b3371d05092aa233b064b03ce7ed", "shasum": "" }, "require": { @@ -5518,7 +5518,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.2.5" + "source": "https://github.com/symfony/http-foundation/tree/v6.2.6" }, "funding": [ { @@ -5534,20 +5534,20 @@ "type": "tidelift" } ], - "time": "2023-01-01T08:38:09+00:00" + "time": "2023-01-30T15:46:28+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.2.5", + "version": "v6.2.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "f68aaa11eee6b21c99bce0f3d98815924888fe62" + "reference": "7122db07b0d8dbf0de682267c84217573aee3ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f68aaa11eee6b21c99bce0f3d98815924888fe62", - "reference": "f68aaa11eee6b21c99bce0f3d98815924888fe62", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/7122db07b0d8dbf0de682267c84217573aee3ea7", + "reference": "7122db07b0d8dbf0de682267c84217573aee3ea7", "shasum": "" }, "require": { @@ -5629,7 +5629,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.2.5" + "source": "https://github.com/symfony/http-kernel/tree/v6.2.6" }, "funding": [ { @@ -5645,7 +5645,7 @@ "type": "tidelift" } ], - "time": "2023-01-24T15:33:24+00:00" + "time": "2023-02-01T08:32:25+00:00" }, { "name": "symfony/intl", @@ -7668,16 +7668,16 @@ }, { "name": "symfony/security-http", - "version": "v6.2.5", + "version": "v6.2.6", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "5c8f064e34f3a320ab02874bdc4591197ba05b20" + "reference": "77c95eada3e3f0bf3a50f89817a18819b357376e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/5c8f064e34f3a320ab02874bdc4591197ba05b20", - "reference": "5c8f064e34f3a320ab02874bdc4591197ba05b20", + "url": "https://api.github.com/repos/symfony/security-http/zipball/77c95eada3e3f0bf3a50f89817a18819b357376e", + "reference": "77c95eada3e3f0bf3a50f89817a18819b357376e", "shasum": "" }, "require": { @@ -7733,7 +7733,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v6.2.5" + "source": "https://github.com/symfony/security-http/tree/v6.2.6" }, "funding": [ { @@ -7749,7 +7749,7 @@ "type": "tidelift" } ], - "time": "2023-01-24T13:16:10+00:00" + "time": "2023-01-30T15:46:28+00:00" }, { "name": "symfony/serializer", @@ -9633,22 +9633,23 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.13.2", + "version": "v3.14.2", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496" + "reference": "14f0541651841b63640e7aafad041ad55dc7aa88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/3952f08a81bd3b1b15e11c3de0b6bf037faa8496", - "reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/14f0541651841b63640e7aafad041ad55dc7aa88", + "reference": "14f0541651841b63640e7aafad041ad55dc7aa88", "shasum": "" }, "require": { - "composer/semver": "^3.2", + "composer/semver": "^3.3", "composer/xdebug-handler": "^3.0.3", - "doctrine/annotations": "^1.13", + "doctrine/annotations": "^1.14.2 || ^2", + "doctrine/lexer": "^2", "ext-json": "*", "ext-tokenizer": "*", "php": "^7.4 || ^8.0", @@ -9658,26 +9659,26 @@ "symfony/filesystem": "^5.4 || ^6.0", "symfony/finder": "^5.4 || ^6.0", "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php80": "^1.25", - "symfony/polyfill-php81": "^1.25", + "symfony/polyfill-mbstring": "^1.27", + "symfony/polyfill-php80": "^1.27", + "symfony/polyfill-php81": "^1.27", "symfony/process": "^5.4 || ^6.0", "symfony/stopwatch": "^5.4 || ^6.0" }, "require-dev": { "justinrainbow/json-schema": "^5.2", "keradus/cli-executor": "^2.0", - "mikey179/vfsstream": "^1.6.10", - "php-coveralls/php-coveralls": "^2.5.2", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.5.3", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.15", + "phpspec/prophecy": "^1.16", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "phpunitgoodpractices/polyfill": "^1.6", "phpunitgoodpractices/traits": "^1.9.2", - "symfony/phpunit-bridge": "^6.0", + "symfony/phpunit-bridge": "^6.2.3", "symfony/yaml": "^5.4 || ^6.0" }, "suggest": { @@ -9710,7 +9711,7 @@ "description": "A tool to automatically fix PHP code style", "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.13.2" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.14.2" }, "funding": [ { @@ -9718,7 +9719,7 @@ "type": "github" } ], - "time": "2023-01-02T23:53:50+00:00" + "time": "2023-01-29T23:47:01+00:00" }, { "name": "fzaninotto/faker", diff --git a/src/ApiPlatform/IsStudentFilter.php b/src/ApiPlatform/IsStudentFilter.php new file mode 100644 index 0000000..79826d7 --- /dev/null +++ b/src/ApiPlatform/IsStudentFilter.php @@ -0,0 +1,31 @@ + [ + 'property' => 'studentId', + 'type' => 'bool', + 'required' => false, + ], + ]; + } + + protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void + { + if ('is_student' !== $property) { + return; + } + $alias = $queryBuilder->getRootAliases()[0]; + $queryBuilder->andWhere("{$alias}.studentId ".('true' === $value ? 'IS NOT' : 'IS').' NULL'); + } +} diff --git a/src/ApiPlatform/SearchInNamesFilter.php b/src/ApiPlatform/SearchInNamesFilter.php new file mode 100644 index 0000000..ac3a376 --- /dev/null +++ b/src/ApiPlatform/SearchInNamesFilter.php @@ -0,0 +1,35 @@ + [ + 'property' => 'name', + 'type' => 'string', + 'required' => false, + ], + ]; + } + + protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void + { + if ('name' !== $property) { + return; + } + $alias = $queryBuilder->getRootAliases()[0]; + $infoAlias = $queryNameGenerator->generateJoinAlias('info'); + $queryBuilder + ->innerJoin("{$alias}.infos", $infoAlias) + ->andWhere("({$alias}.firstName LIKE '%{$value}%' OR {$alias}.lastName LIKE '%{$value}%' OR {$infoAlias}.nickname LIKE '%{$value}%')") + ; + } +} diff --git a/src/ApiPlatform/UEFilter.php b/src/ApiPlatform/UEFilter.php new file mode 100644 index 0000000..a8344f9 --- /dev/null +++ b/src/ApiPlatform/UEFilter.php @@ -0,0 +1,44 @@ + [ + 'property' => 'ue', + 'type' => 'array', + 'required' => false, + 'is_collection' => true, + ], + ]; + } + + protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void + { + if ('ue' !== $property) { + return; + } + $alias = $queryBuilder->getRootAliases()[0]; + foreach ($value as $ueCode) { + $ueAlias = $queryNameGenerator->generateJoinAlias('UE'); + $ueSubscriptionAlias = $queryNameGenerator->generateJoinAlias('UEsSubscriptions'); + $semesterAlias = $queryNameGenerator->generateJoinAlias('Semester'); + $queryBuilder->innerJoin("{$alias}.UEsSubscriptions", $ueSubscriptionAlias) + ->innerJoin("{$ueSubscriptionAlias}.UE", $ueAlias) + ->innerJoin("{$ueSubscriptionAlias}.semester", $semesterAlias) + ->andWhere("{$ueAlias}.code = '{$ueCode}'") + ->andWhere("{$semesterAlias}.start <= :now") + ->andWhere("{$semesterAlias}.end >= :now") + ; + } + $queryBuilder->setParameter('now', new \DateTime()); + } +} diff --git a/src/Entity/User.php b/src/Entity/User.php index 1a40a10..8c4bbf2 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -2,11 +2,16 @@ namespace App\Entity; +use ApiPlatform\Doctrine\Orm\Filter\SearchFilter; +use ApiPlatform\Metadata\ApiFilter; use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\Delete; use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\GetCollection; use ApiPlatform\Metadata\Patch; +use App\ApiPlatform\IsStudentFilter; +use App\ApiPlatform\SearchInNamesFilter; +use App\ApiPlatform\UEFilter; use App\Controller\GetEDTController; use App\Controller\SoftDeleteController; use App\DataProvider\UserDataVisibilityItemDataProvider; @@ -24,6 +29,7 @@ * The main entity that represents all Users. It is related to UEs, Covoits, Assos and others. * * @ORM\Entity(repositoryClass=UserRepository::class) + * * @ORM\Table(name="users") */ #[ @@ -58,15 +64,33 @@ ], paginationItemsPerPage: 10, security: "is_granted('ROLE_USER')", - ) + ), + ApiFilter( + SearchFilter::class, + properties: [ + 'studentId' => 'exact', + 'mailsPhones.mailPersonal' => 'exact', + 'mailsPhones.phoneNumber' => 'exact', + 'branche.branche.code' => 'exact', + 'branche.filiere.code' => 'exact', + 'branche.semesterNumber' => 'exact', + ] + ), + ApiFilter(UEFilter::class), + ApiFilter(SearchInNamesFilter::class), + ApiFilter(IsStudentFilter::class), ] class User implements UserInterface { /** * @ORM\Id + * * @ORM\Column(type="uuid", unique=true) + * * @ORM\GeneratedValue(strategy="CUSTOM") + * * @ORM\CustomIdGenerator(class=UuidGenerator::class) + * * @Assert\Uuid() */ #[Groups([ @@ -79,8 +103,11 @@ class User implements UserInterface * The CAS login of the User. * * @ORM\Column(type="string", length=50, unique=true) + * * @Assert\Type("string") + * * @Assert\Length(max=50) + * * @Assert\Regex("/^[a-z_0-9]{1,50}$/") */ #[Groups([ @@ -93,7 +120,9 @@ class User implements UserInterface * For the User that are students, this is the UTT student number. * * @ORM\Column(type="integer", nullable=true, unique=true) + * * @Assert\Type("int") + * * @Assert\Positive */ #[Groups([ @@ -103,7 +132,9 @@ class User implements UserInterface /** * @ORM\Column(type="string", length=255) + * * @Assert\Type("string") + * * @Assert\Length(max=255) */ #[Groups([ @@ -114,7 +145,9 @@ class User implements UserInterface /** * @ORM\Column(type="string", length=255) + * * @Assert\Type("string") + * * @Assert\Length(max=255) */ #[Groups([ @@ -141,6 +174,7 @@ class User implements UserInterface * The relation to the entity that contains the User's SocialNetwork. * * @ORM\OneToOne(targetEntity=UserSocialNetwork::class, mappedBy="user", cascade={"persist", "remove"}) + * * @Assert\Valid() */ #[Groups([ @@ -160,6 +194,7 @@ class User implements UserInterface * The relation to the entity that contains the User's RGPD. * * @ORM\OneToOne(targetEntity=UserRGPD::class, mappedBy="user", cascade={"persist", "remove"}) + * * @Assert\Valid() */ #[Groups([ @@ -244,6 +279,7 @@ class User implements UserInterface * The relation to the Preference of the User. * * @ORM\OneToOne(targetEntity=UserPreference::class, mappedBy="user", cascade={"persist", "remove"}) + * * @Assert\Valid() */ #[Groups([ @@ -256,6 +292,7 @@ class User implements UserInterface * The relation to the Infos of the User. * * @ORM\OneToOne(targetEntity=UserInfos::class, mappedBy="user", cascade={"persist", "remove"}) + * * @Assert\Valid() */ #[Groups([ @@ -269,6 +306,7 @@ class User implements UserInterface * The relation to the Addresses of the User. * * @ORM\OneToMany(targetEntity=UserAddress::class, mappedBy="user", cascade={"persist", "remove"}, orphanRemoval=true) + * * @Assert\Valid() */ #[Groups([ @@ -281,6 +319,7 @@ class User implements UserInterface * The relation to mails and phone number of the User. * * @ORM\OneToOne(targetEntity=UserMailsPhones::class, mappedBy="user", cascade={"persist", "remove"}) + * * @Assert\Valid() */ #[Groups([ diff --git a/src/Entity/UserInfos.php b/src/Entity/UserInfos.php index 6d5b9b1..f2b0c81 100644 --- a/src/Entity/UserInfos.php +++ b/src/Entity/UserInfos.php @@ -125,6 +125,7 @@ class UserInfos */ #[Groups([ 'user:read:one', + 'user:read:some', 'user:write:update', ])] private $nickname;