Merge branch 'develop' into feat/271-expedition-etape-1

# Conflicts:
#	.idea/data_source_mapping.xml
#	src/Entity/Carrier.php
This commit is contained in:
2026-02-10 08:59:24 +01:00
34 changed files with 1116 additions and 308 deletions

View File

@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace App\ApiResource;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use App\State\AppVersionProvider;
use Symfony\Component\Serializer\Attribute\Groups;
#[ApiResource(
operations: [
new Get(
uriTemplate: '/version',
normalizationContext: ['groups' => ['version:read']],
provider: AppVersionProvider::class,
),
],
)]
final class AppVersion
{
#[Groups(['version:read'])]
public string $version = '';
}

View File

View File

@@ -7,6 +7,8 @@ namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Attribute\Groups;
@@ -21,6 +23,15 @@ use Symfony\Component\Serializer\Attribute\Groups;
new GetCollection(
normalizationContext: ['groups' => ['carrier:read']],
),
new Post(
normalizationContext: ['groups' => ['carrier:read']],
denormalizationContext: ['groups' => ['carrier:write']],
),
new Patch(
requirements: ['id' => '\d+'],
normalizationContext: ['groups' => ['carrier:read']],
denormalizationContext: ['groups' => ['carrier:write']],
),
],
security: "is_granted('ROLE_USER')",
)]
@@ -33,11 +44,11 @@ class Carrier
private ?int $id = null;
#[ORM\Column(length: 180)]
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read', 'shipment:read'])]
#[Groups(['carrier:read', 'carrier:write', 'driver:read', 'vehicle:read', 'reception:read', 'shipment:read'])]
private string $name = '';
#[ORM\Column(length: 30, nullable: true)]
#[Groups(['carrier:read', 'driver:read', 'vehicle:read', 'reception:read', 'shipment:read'])]
#[Groups(['carrier:read', 'carrier:write', 'driver:read', 'vehicle:read', 'reception:read', 'shipment:read'])]
private ?string $code = null;
public function getId(): ?int

View File

@@ -7,7 +7,10 @@ namespace App\Entity;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Patch;
use ApiPlatform\Metadata\Post;
use App\State\MeProvider;
use App\State\UserPasswordProcessor;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
@@ -28,10 +31,27 @@ use Symfony\Component\Serializer\Attribute\Groups;
normalizationContext: ['groups' => ['user:read']],
security: "is_granted('ROLE_USER')"
),
new GetCollection(
new Post(
normalizationContext: ['groups' => ['user:read']],
denormalizationContext: ['groups' => ['user:write']],
security: "is_granted('ROLE_ADMIN')",
processor: UserPasswordProcessor::class
),
new Patch(
normalizationContext: ['groups' => ['user:read']],
denormalizationContext: ['groups' => ['user:write']],
security: "is_granted('ROLE_ADMIN')",
processor: UserPasswordProcessor::class
),
new GetCollection(
normalizationContext: ['groups' => ['user-login:read']],
security: "is_granted('PUBLIC_ACCESS')"
),
new GetCollection(
uriTemplate: '/admin/users',
normalizationContext: ['groups' => ['user:read']],
security: "is_granted('ROLE_ADMIN')"
),
],
normalizationContext: ['groups' => ['user:read']],
paginationEnabled: false
@@ -41,17 +61,19 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
#[Groups(['user:read', 'reception:read'])]
#[Groups(['user:read', 'user-login:read', 'reception:read'])]
private ?int $id = null;
#[ORM\Column(length: 180, unique: true)]
#[Groups(['user:read', 'reception:read'])]
#[Groups(['user:read', 'user:write', 'user-login:read', 'reception:read'])]
private string $username = '';
#[ORM\Column(type: 'json')]
#[Groups(['user:write', 'user:read'])]
private array $roles = [];
#[ORM\Column]
#[Groups(['user:write'])]
private string $password = '';
public function getId(): ?int

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\ApiResource\AppVersion;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
final readonly class AppVersionProvider implements ProviderInterface
{
public function __construct(
#[Autowire('%app.version%')]
private string $version,
) {}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): AppVersion
{
$dto = new AppVersion();
$dto->version = $this->version;
return $dto;
}
}

View File

@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProcessorInterface;
use App\Entity\User;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
final class UserPasswordProcessor implements ProcessorInterface
{
public function __construct(
private readonly UserPasswordHasherInterface $hasher,
#[Autowire(service: 'api_platform.doctrine.orm.state.persist_processor')]
private readonly ProcessorInterface $persistProcessor
) {}
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): mixed
{
if ($data instanceof User) {
$plain = $data->getPassword();
if ('' !== $plain) {
$data->setPassword($this->hasher->hashPassword(
$data,
$plain
));
}
}
return $this->persistProcessor->process(
$data,
$operation,
$uriVariables,
$context
);
}
}