- Extract shared ID generation + timestamps into CuidEntityTrait used by all entities - Create AbstractAuditSubscriber to deduplicate audit logic across 7 subscribers - Merge per-entity history controllers into single EntityHistoryController - Delete redundant ComposantHistory/MachineHistory/PieceHistory/ProductHistoryController - Add OpenApiDecorator for API documentation customization - Disable failOnDeprecation in PHPUnit (vendor API Platform deprecation) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
208 lines
5.3 KiB
PHP
208 lines
5.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Entity;
|
|
|
|
use ApiPlatform\Doctrine\Orm\Filter\OrderFilter;
|
|
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\Entity\Trait\CuidEntityTrait;
|
|
use DateTimeImmutable;
|
|
use Doctrine\DBAL\Types\Types;
|
|
use Doctrine\ORM\Mapping as ORM;
|
|
|
|
#[ORM\Entity]
|
|
#[ORM\Table(name: 'comments')]
|
|
#[ORM\Index(columns: ['entity_type', 'entity_id', 'status'], name: 'idx_comment_entity_status')]
|
|
#[ORM\HasLifecycleCallbacks]
|
|
#[ApiFilter(SearchFilter::class, properties: ['entityType' => 'exact', 'entityId' => 'exact', 'status' => 'exact', 'entityName' => 'ipartial'])]
|
|
#[ApiFilter(OrderFilter::class, properties: ['createdAt', 'authorName', 'status'])]
|
|
#[ApiResource(
|
|
description: 'Commentaires et annotations. Permet aux utilisateurs de commenter les machines, pièces, composants, produits et catégories. Les commentaires peuvent être marqués comme résolus.',
|
|
operations: [
|
|
new Get(security: "is_granted('ROLE_VIEWER')"),
|
|
new GetCollection(security: "is_granted('ROLE_VIEWER')"),
|
|
new Patch(security: "is_granted('ROLE_GESTIONNAIRE')"),
|
|
new Delete(security: "is_granted('ROLE_GESTIONNAIRE')"),
|
|
],
|
|
order: ['createdAt' => 'DESC'],
|
|
paginationClientItemsPerPage: true,
|
|
paginationMaximumItemsPerPage: 200
|
|
)]
|
|
class Comment
|
|
{
|
|
use CuidEntityTrait;
|
|
|
|
#[ORM\Id]
|
|
#[ORM\Column(type: Types::STRING, length: 36)]
|
|
private ?string $id = null;
|
|
|
|
#[ORM\Column(type: Types::TEXT)]
|
|
private string $content;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 50, name: 'entity_type')]
|
|
private string $entityType;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 36, name: 'entity_id')]
|
|
private string $entityId;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 255, nullable: true, name: 'entity_name')]
|
|
private ?string $entityName = null;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 36, name: 'author_id')]
|
|
private string $authorId;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 255, name: 'author_name')]
|
|
private string $authorName;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 20)]
|
|
private string $status = 'open';
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 36, nullable: true, name: 'resolved_by_id')]
|
|
private ?string $resolvedById = null;
|
|
|
|
#[ORM\Column(type: Types::STRING, length: 255, nullable: true, name: 'resolved_by_name')]
|
|
private ?string $resolvedByName = null;
|
|
|
|
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: true, name: 'resolved_at')]
|
|
private ?DateTimeImmutable $resolvedAt = null;
|
|
|
|
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'created_at')]
|
|
private DateTimeImmutable $createdAt;
|
|
|
|
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, name: 'updated_at')]
|
|
private DateTimeImmutable $updatedAt;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->createdAt = new DateTimeImmutable();
|
|
$this->updatedAt = new DateTimeImmutable();
|
|
}
|
|
|
|
public function getContent(): string
|
|
{
|
|
return $this->content;
|
|
}
|
|
|
|
public function setContent(string $content): static
|
|
{
|
|
$this->content = $content;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getEntityType(): string
|
|
{
|
|
return $this->entityType;
|
|
}
|
|
|
|
public function setEntityType(string $entityType): static
|
|
{
|
|
$this->entityType = $entityType;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getEntityId(): string
|
|
{
|
|
return $this->entityId;
|
|
}
|
|
|
|
public function setEntityId(string $entityId): static
|
|
{
|
|
$this->entityId = $entityId;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getEntityName(): ?string
|
|
{
|
|
return $this->entityName;
|
|
}
|
|
|
|
public function setEntityName(?string $entityName): static
|
|
{
|
|
$this->entityName = $entityName;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getAuthorId(): string
|
|
{
|
|
return $this->authorId;
|
|
}
|
|
|
|
public function setAuthorId(string $authorId): static
|
|
{
|
|
$this->authorId = $authorId;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getAuthorName(): string
|
|
{
|
|
return $this->authorName;
|
|
}
|
|
|
|
public function setAuthorName(string $authorName): static
|
|
{
|
|
$this->authorName = $authorName;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getStatus(): string
|
|
{
|
|
return $this->status;
|
|
}
|
|
|
|
public function setStatus(string $status): static
|
|
{
|
|
$this->status = $status;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getResolvedById(): ?string
|
|
{
|
|
return $this->resolvedById;
|
|
}
|
|
|
|
public function setResolvedById(?string $resolvedById): static
|
|
{
|
|
$this->resolvedById = $resolvedById;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getResolvedByName(): ?string
|
|
{
|
|
return $this->resolvedByName;
|
|
}
|
|
|
|
public function setResolvedByName(?string $resolvedByName): static
|
|
{
|
|
$this->resolvedByName = $resolvedByName;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getResolvedAt(): ?DateTimeImmutable
|
|
{
|
|
return $this->resolvedAt;
|
|
}
|
|
|
|
public function setResolvedAt(?DateTimeImmutable $resolvedAt): static
|
|
{
|
|
$this->resolvedAt = $resolvedAt;
|
|
|
|
return $this;
|
|
}
|
|
}
|