Loading .idea/php.xml +15 −0 Changes for .idea/php.xml: 15 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -15,6 +15,11 @@ <PhpCSFixerConfiguration tool_path="$PROJECT_DIR$/api/vendor/bin/php-cs-fixer" /> </phpcsfixer_settings> </component> <component name="PhpCodeSniffer"> <phpcs_settings> <phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="1a2783e3-abfb-4146-8fd6-6d28367f961a" timeout="30000" /> </phpcs_settings> </component> <component name="PhpIncludePathManager"> <include_path> <path value="$PROJECT_DIR$/api/vendor/symfony/serializer" /> Loading Loading @@ -89,6 +94,11 @@ </include_path> </component> <component name="PhpProjectSharedConfiguration" php_language_level="8.2" /> <component name="PhpStan"> <PhpStan_settings> <phpstan_by_interpreter asDefaultInterpreter="true" interpreter_id="1a2783e3-abfb-4146-8fd6-6d28367f961a" timeout="60000" /> </PhpStan_settings> </component> <component name="PhpStanOptionsConfiguration"> <option name="transferred" value="true" /> </component> Loading @@ -97,6 +107,11 @@ <PhpUnitSettings custom_loader_path="$PROJECT_DIR$/api/vendor/autoload.php" /> </phpunit_settings> </component> <component name="Psalm"> <Psalm_settings> <psalm_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="1a2783e3-abfb-4146-8fd6-6d28367f961a" timeout="60000" /> </Psalm_settings> </component> <component name="PsalmOptionsConfiguration"> <option name="transferred" value="true" /> </component> Loading api/composer.json +1 −1 Changes for api/composer.json: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ "php": "^8.2", "doctrine/orm": "^3.3", "api-platform/core": "^4.1", "symfony/security-bundle": "^7.2", "symfony/security-bundle": "^7.3", "symfony/validator": "^7.3" }, "require-dev": { Loading api/src/Command/SyncApiRoutesCommand.php +27 −29 Changes for api/src/Command/SyncApiRoutesCommand.php: 27 added lines, 29 removed lines. Original line number Diff line number Diff line Loading @@ -2,8 +2,6 @@ namespace Unicaen\Privilege\Command; use ApiPlatform\Metadata\HttpOperation; use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; Loading @@ -11,6 +9,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Unicaen\Privilege\Entity\PrivilegeRoute; use Unicaen\Privilege\Service\RouteService; #[AsCommand( name: 'unicaen:privilege:sync-routes', Loading @@ -19,7 +18,7 @@ use Unicaen\Privilege\Entity\PrivilegeRoute; class SyncApiRoutesCommand extends Command { public function __construct( private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory, private readonly RouteService $routeService, private readonly EntityManagerInterface $em, ) { parent::__construct(); Loading @@ -30,38 +29,37 @@ class SyncApiRoutesCommand extends Command $io = new SymfonyStyle($input, $output); $repo = $this->em->getRepository(PrivilegeRoute::class); $count = 0; foreach ($this->resourceMetadataFactory->create() as $resourceClass => $collection) { foreach ($collection as $resourceMetadata) { foreach ($resourceMetadata->getOperations() ?? [] as $operation) { if (!$operation instanceof HttpOperation) { continue; } $io->title('Synchronisation des routes API Platform'); $io->text('Récupération des routes API Platform...'); $routes = $this->routeService->listApiRoutes(); $io->success('Récupération des routes terminée.'); $io->text("Ajout des routes (".count($routes).") dans la base de données..."); $routeName = $operation->getRouteName(); $method = $operation->getMethod(); $path = $operation->getUriTemplate(); $operationName = $operation->getName(); $operationType = (new \ReflectionClass($operation))->getShortName(); $nAddedRoutes = 0; foreach ($routes as $route) { $existingRoute = $repo->findOneBy([ 'resource' => $route['resource'], 'name' => $route['name'], 'method' => $route['method'], 'path' => $route['path'], ]); $existing = $repo->findOneBy(['routeName' => $routeName]); if (!$existingRoute) { $newRoute = new PrivilegeRoute(); $newRoute->setResource($route['resource']) ->setName($route['name']) ->setMethod($route['method']) ->setPath($route['path']) ->setShortName($route['shortName'] ?? null) ->setOperationType($route['operationType'] ?? null); if (!$existing) { $route = new PrivilegeRoute(); $route->setRouteName($routeName); $route->setMethod($method); $route->setPath($path); $route->setResourceClass($resourceClass); $route->setOperationName($operationName); $route->setOperationType($operationType); $this->em->persist($route); ++$count; } } $this->em->persist($newRoute); $nAddedRoutes++; } } $this->em->flush(); $io->success("Synchronisation terminée : $count nouvelles routes ajoutées."); $io->success("Synchronisation terminée : $nAddedRoutes nouvelles routes ajoutées."); return Command::SUCCESS; } Loading api/src/Entity/Privilege.php +75 −4 Changes for api/src/Entity/Privilege.php: 75 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ use ApiPlatform\Metadata\ApiResource; use ApiPlatform\OpenApi\Model\Operation; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity] Loading @@ -13,24 +14,32 @@ use Symfony\Component\Validator\Constraints as Assert; #[ApiResource( openapi: new Operation( tags: ['unicaen_privilege Privilege'], ) ), security: "is_granted('UNICAEN_PRIVILEGE', object)", )] class Privilege { #[ORM\Id, ORM\GeneratedValue, ORM\Column] private ?int $id = null; #[ORM\Column(length: 255)] #[ORM\Column(length: 255, unique: true)] private ?string $code; #[ORM\Column(unique: true)] #[Assert\NotBlank(message: 'Le nom ne peut être vide.')] #[ORM\Column(length: 255)] private string $name; #[ORM\ManyToOne(targetEntity: PrivilegeCategorie::class)] #[ORM\ManyToOne(targetEntity: PrivilegeCategorie::class, inversedBy: 'privileges')] #[Assert\NotBlank(message: 'Categorie cannot be blank.')] private ?PrivilegeCategorie $category = null; #[ORM\ManyToMany(targetEntity: PrivilegeRoute::class, inversedBy: 'privileges')] #[ORM\JoinTable(name: 'unicaen_privilege_privilege_route')] private Collection $routes; #[ORM\ManyToMany(targetEntity: Role::class, mappedBy: 'privileges')] private Collection $roles; public function getId(): ?int { return $this->id; Loading Loading @@ -71,4 +80,66 @@ class Privilege return $this; } public function getRoutes(): Collection { return $this->routes; } public function setRoutes(Collection $routes): self { $this->routes = $routes; return $this; } public function addRoute(PrivilegeRoute $route): self { if (!$this->routes->contains($route)) { $this->routes->add($route); $route->getPrivileges()->add($this); } return $this; } public function removeRoute(PrivilegeRoute $route): self { if ($this->routes->removeElement($route)) { $route->getPrivileges()->removeElement($this); } return $this; } public function getRoles(): Collection { return $this->roles; } public function setRoles(Collection $roles): self { $this->roles = $roles; return $this; } public function addRole(Role $role): self { if (!$this->roles->contains($role)) { $this->roles->add($role); $role->getPrivileges()->add($this); } return $this; } public function removeRole(Role $role): self { if ($this->roles->removeElement($role)) { $role->getPrivileges()->removeElement($this); } return $this; } } api/src/Entity/PrivilegeCategorie.php +16 −0 Changes for api/src/Entity/PrivilegeCategorie.php: 16 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ namespace Unicaen\Privilege\Entity; use ApiPlatform\Metadata\ApiResource; use ApiPlatform\OpenApi\Model\Operation; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] Loading @@ -22,6 +23,9 @@ class PrivilegeCategorie #[ORM\Column(unique: true)] private string $name; #[ORM\OneToMany(targetEntity: Privilege::class, mappedBy: 'category', cascade: ['remove'], orphanRemoval: true)] private Collection $privileges; public function getId(): ?int { return $this->id; Loading @@ -38,4 +42,16 @@ class PrivilegeCategorie return $this; } public function getPrivileges(): Collection { return $this->privileges; } public function setPrivileges(Collection $privileges): self { $this->privileges = $privileges; return $this; } } Loading
.idea/php.xml +15 −0 Changes for .idea/php.xml: 15 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -15,6 +15,11 @@ <PhpCSFixerConfiguration tool_path="$PROJECT_DIR$/api/vendor/bin/php-cs-fixer" /> </phpcsfixer_settings> </component> <component name="PhpCodeSniffer"> <phpcs_settings> <phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="1a2783e3-abfb-4146-8fd6-6d28367f961a" timeout="30000" /> </phpcs_settings> </component> <component name="PhpIncludePathManager"> <include_path> <path value="$PROJECT_DIR$/api/vendor/symfony/serializer" /> Loading Loading @@ -89,6 +94,11 @@ </include_path> </component> <component name="PhpProjectSharedConfiguration" php_language_level="8.2" /> <component name="PhpStan"> <PhpStan_settings> <phpstan_by_interpreter asDefaultInterpreter="true" interpreter_id="1a2783e3-abfb-4146-8fd6-6d28367f961a" timeout="60000" /> </PhpStan_settings> </component> <component name="PhpStanOptionsConfiguration"> <option name="transferred" value="true" /> </component> Loading @@ -97,6 +107,11 @@ <PhpUnitSettings custom_loader_path="$PROJECT_DIR$/api/vendor/autoload.php" /> </phpunit_settings> </component> <component name="Psalm"> <Psalm_settings> <psalm_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="1a2783e3-abfb-4146-8fd6-6d28367f961a" timeout="60000" /> </Psalm_settings> </component> <component name="PsalmOptionsConfiguration"> <option name="transferred" value="true" /> </component> Loading
api/composer.json +1 −1 Changes for api/composer.json: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ "php": "^8.2", "doctrine/orm": "^3.3", "api-platform/core": "^4.1", "symfony/security-bundle": "^7.2", "symfony/security-bundle": "^7.3", "symfony/validator": "^7.3" }, "require-dev": { Loading
api/src/Command/SyncApiRoutesCommand.php +27 −29 Changes for api/src/Command/SyncApiRoutesCommand.php: 27 added lines, 29 removed lines. Original line number Diff line number Diff line Loading @@ -2,8 +2,6 @@ namespace Unicaen\Privilege\Command; use ApiPlatform\Metadata\HttpOperation; use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; Loading @@ -11,6 +9,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Unicaen\Privilege\Entity\PrivilegeRoute; use Unicaen\Privilege\Service\RouteService; #[AsCommand( name: 'unicaen:privilege:sync-routes', Loading @@ -19,7 +18,7 @@ use Unicaen\Privilege\Entity\PrivilegeRoute; class SyncApiRoutesCommand extends Command { public function __construct( private readonly ResourceMetadataCollectionFactoryInterface $resourceMetadataFactory, private readonly RouteService $routeService, private readonly EntityManagerInterface $em, ) { parent::__construct(); Loading @@ -30,38 +29,37 @@ class SyncApiRoutesCommand extends Command $io = new SymfonyStyle($input, $output); $repo = $this->em->getRepository(PrivilegeRoute::class); $count = 0; foreach ($this->resourceMetadataFactory->create() as $resourceClass => $collection) { foreach ($collection as $resourceMetadata) { foreach ($resourceMetadata->getOperations() ?? [] as $operation) { if (!$operation instanceof HttpOperation) { continue; } $io->title('Synchronisation des routes API Platform'); $io->text('Récupération des routes API Platform...'); $routes = $this->routeService->listApiRoutes(); $io->success('Récupération des routes terminée.'); $io->text("Ajout des routes (".count($routes).") dans la base de données..."); $routeName = $operation->getRouteName(); $method = $operation->getMethod(); $path = $operation->getUriTemplate(); $operationName = $operation->getName(); $operationType = (new \ReflectionClass($operation))->getShortName(); $nAddedRoutes = 0; foreach ($routes as $route) { $existingRoute = $repo->findOneBy([ 'resource' => $route['resource'], 'name' => $route['name'], 'method' => $route['method'], 'path' => $route['path'], ]); $existing = $repo->findOneBy(['routeName' => $routeName]); if (!$existingRoute) { $newRoute = new PrivilegeRoute(); $newRoute->setResource($route['resource']) ->setName($route['name']) ->setMethod($route['method']) ->setPath($route['path']) ->setShortName($route['shortName'] ?? null) ->setOperationType($route['operationType'] ?? null); if (!$existing) { $route = new PrivilegeRoute(); $route->setRouteName($routeName); $route->setMethod($method); $route->setPath($path); $route->setResourceClass($resourceClass); $route->setOperationName($operationName); $route->setOperationType($operationType); $this->em->persist($route); ++$count; } } $this->em->persist($newRoute); $nAddedRoutes++; } } $this->em->flush(); $io->success("Synchronisation terminée : $count nouvelles routes ajoutées."); $io->success("Synchronisation terminée : $nAddedRoutes nouvelles routes ajoutées."); return Command::SUCCESS; } Loading
api/src/Entity/Privilege.php +75 −4 Changes for api/src/Entity/Privilege.php: 75 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ use ApiPlatform\Metadata\ApiResource; use ApiPlatform\OpenApi\Model\Operation; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity] Loading @@ -13,24 +14,32 @@ use Symfony\Component\Validator\Constraints as Assert; #[ApiResource( openapi: new Operation( tags: ['unicaen_privilege Privilege'], ) ), security: "is_granted('UNICAEN_PRIVILEGE', object)", )] class Privilege { #[ORM\Id, ORM\GeneratedValue, ORM\Column] private ?int $id = null; #[ORM\Column(length: 255)] #[ORM\Column(length: 255, unique: true)] private ?string $code; #[ORM\Column(unique: true)] #[Assert\NotBlank(message: 'Le nom ne peut être vide.')] #[ORM\Column(length: 255)] private string $name; #[ORM\ManyToOne(targetEntity: PrivilegeCategorie::class)] #[ORM\ManyToOne(targetEntity: PrivilegeCategorie::class, inversedBy: 'privileges')] #[Assert\NotBlank(message: 'Categorie cannot be blank.')] private ?PrivilegeCategorie $category = null; #[ORM\ManyToMany(targetEntity: PrivilegeRoute::class, inversedBy: 'privileges')] #[ORM\JoinTable(name: 'unicaen_privilege_privilege_route')] private Collection $routes; #[ORM\ManyToMany(targetEntity: Role::class, mappedBy: 'privileges')] private Collection $roles; public function getId(): ?int { return $this->id; Loading Loading @@ -71,4 +80,66 @@ class Privilege return $this; } public function getRoutes(): Collection { return $this->routes; } public function setRoutes(Collection $routes): self { $this->routes = $routes; return $this; } public function addRoute(PrivilegeRoute $route): self { if (!$this->routes->contains($route)) { $this->routes->add($route); $route->getPrivileges()->add($this); } return $this; } public function removeRoute(PrivilegeRoute $route): self { if ($this->routes->removeElement($route)) { $route->getPrivileges()->removeElement($this); } return $this; } public function getRoles(): Collection { return $this->roles; } public function setRoles(Collection $roles): self { $this->roles = $roles; return $this; } public function addRole(Role $role): self { if (!$this->roles->contains($role)) { $this->roles->add($role); $role->getPrivileges()->add($this); } return $this; } public function removeRole(Role $role): self { if ($this->roles->removeElement($role)) { $role->getPrivileges()->removeElement($this); } return $this; } }
api/src/Entity/PrivilegeCategorie.php +16 −0 Changes for api/src/Entity/PrivilegeCategorie.php: 16 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ namespace Unicaen\Privilege\Entity; use ApiPlatform\Metadata\ApiResource; use ApiPlatform\OpenApi\Model\Operation; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] Loading @@ -22,6 +23,9 @@ class PrivilegeCategorie #[ORM\Column(unique: true)] private string $name; #[ORM\OneToMany(targetEntity: Privilege::class, mappedBy: 'category', cascade: ['remove'], orphanRemoval: true)] private Collection $privileges; public function getId(): ?int { return $this->id; Loading @@ -38,4 +42,16 @@ class PrivilegeCategorie return $this; } public function getPrivileges(): Collection { return $this->privileges; } public function setPrivileges(Collection $privileges): self { $this->privileges = $privileges; return $this; } }