diff --git a/diagrams/database.drawio b/diagrams/database.drawio index 35c06b4..7172e9f 100644 --- a/diagrams/database.drawio +++ b/diagrams/database.drawio @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/Entity/Document.php b/src/Entity/Document.php index c5c1000..287223c 100644 --- a/src/Entity/Document.php +++ b/src/Entity/Document.php @@ -7,127 +7,261 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -use Gedmo\Mapping\Annotation\Timestampable; +use Gedmo\Mapping\Annotation as Gedmo; +use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity(repositoryClass: DocumentRepository::class)] -class Document -{ - #[ORM\Id] - #[ORM\GeneratedValue] - #[ORM\Column] - private ?int $id = null; +#[Gedmo\Uploadable( + pathMethod: 'getFileDirectoryPath', + callback: 'onFileMove', + filenameGenerator: 'SHA1', + maxSize: 20 * 1024 * 1024, // 20 Mo +)] +class Document { + use TEntityBase; + /** + * @var User The owner + */ #[ORM\ManyToOne] #[ORM\JoinColumn(nullable: false)] - private ?User $user = null; + #[Assert\Valid] + private User $owner; + /** + * @var string The file path, relative to owner directory (aka “file name”) + */ + #[ORM\Column(length: 255)] + #[Gedmo\UploadableFileName] + #[Assert\NotBlank] + private string $filePath; + /** + * @var string The original file name + */ + #[ORM\Column(length: 255)] + #[Assert\NotBlank] + private string $fileName; + /** + * @var string The file mime type + */ #[ORM\Column(length: 255)] - private ?string $name = null; + #[Gedmo\UploadableFileMimeType] + #[Assert\NotBlank] + private string $fileType; + /** + * @var int The file size, in bytes + */ + #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 0)] // En "decimal" dans Doctrine car Gedmo\UploadableFileSize l'impose, mais bien un entier derrière + #[Gedmo\UploadableFileSize] + #[Assert\Positive] + private int $fileSize; + /** + * @var string|null The description + */ #[ORM\Column(type: Types::TEXT, nullable: true)] private ?string $description = null; - #[ORM\Column(type: Types::DATETIME_IMMUTABLE)] - #[Timestampable(on: 'create')] - private ?\DateTimeInterface $creation = null; - - #[ORM\Column(type: Types::DATETIME_IMMUTABLE)] - #[Timestampable] - private ?\DateTimeInterface $modification = null; - + /** + * @var Collection The {@see Tag tags} + */ #[ORM\ManyToMany(targetEntity: Tag::class, inversedBy: 'documents')] private Collection $tags; + /** + * Initialization + */ public function __construct () { $this->tags = new ArrayCollection(); } - public function getId(): ?int - { - return $this->id; + /** + * The owner + * + * @return User The owner + */ + public function getOwner (): User { + return $this->owner; } + /** + * Change the owner + * + * @param User $owner The new owner + * + * @return $this + */ + public function setOwner (User $owner): self { + $this->owner = $owner; - public function getUser(): ?User - { - return $this->user; + return $this; } - public function setUser(?User $user): self - { - $this->user = $user; + /** + * The file path, relative to owner directory (aka “file name”) + * + * @return string|null The file path, relative to owner directory (aka “file name”) + */ + public function getFilePath (): ?string { + return $this->filePath; + } + /** + * Change the file path, relative to owner directory (aka “file name”) + * + * @param string $filePath The new file path, relative to owner directory (aka “file name”) + * + * @return $this + */ + public function setFilePath (string $filePath): static { + $this->filePath = $filePath; return $this; } - public function getName(): ?string - { - return $this->name; + /** + * The original file name + * + * @return string|null The original file name + */ + public function getFileName (): ?string { + return $this->fileName; } - - public function setName(string $name): self - { - $this->name = $name; + /** + * Change the original file name + * + * @param string $fileName The new original file name + * + * @return $this + */ + public function setFileName (string $fileName): static { + $this->fileName = $fileName; return $this; } - public function getDescription(): ?string - { - return $this->description; + /** + * The file mime type + * + * @return string|null The file mime type + */ + public function getFileType (): ?string { + return $this->fileType; } - - public function setDescription(?string $description): self - { - $this->description = $description; + /** + * Change the file mime type + * + * @param string $fileType The new file mime type + * + * @return $this + */ + public function setFileType (string $fileType): static { + $this->fileType = $fileType; return $this; } - public function getCreation(): ?\DateTimeInterface - { - return $this->creation; + /** + * The file size, in bytes + * + * @return int|null The file size, in bytes + */ + public function getFileSize (): ?int { + return $this->fileSize; } - - public function setCreation(\DateTimeInterface $creation): self - { - $this->creation = $creation; + /** + * Change the file size, in bytes + * + * @param int $fileSize The new file size, in bytes + * + * @return $this + */ + public function setFileSize (int $fileSize): static { + $this->fileSize = $fileSize; return $this; } - public function getModification(): ?\DateTimeInterface - { - return $this->modification; + /** + * The description + * + * @return string|null The description + */ + public function getDescription (): ?string { + return $this->description; } - - public function setModification(\DateTimeInterface $modification): self - { - $this->modification = $modification; + /** + * Change the description + * + * @param string|null $description The new description + * + * @return $this + */ + public function setDescription (?string $description): self { + $this->description = $description; return $this; } /** - * @return Collection + * The {@see Tag tags} + * + * @return Collection The {@see Tag tags} */ - public function getTags(): Collection - { + public function getTags (): Collection { return $this->tags; } - - public function addTag(Tag $tag): self - { + /** + * Add a tag + * + * Do nothing if the tag is already present + * + * @param Tag $tag The tag to add + * + * @return $this + */ + public function addTag (Tag $tag): self { if (!$this->tags->contains($tag)) { $this->tags->add($tag); } - return $this; } - - public function removeTag(Tag $tag): self - { + /** + * Remove a tag + * + * @param Tag $tag The tag to remove + * + * @return $this + */ + public function removeTag (Tag $tag): self { $this->tags->removeElement($tag); - return $this; } + + /** + * The file directory path + * + * @param string $globalFileDirectoryPath The global file directory path + * + * @return string The file directory path + * + * @see \Gedmo\Mapping\Annotation\Uploadable::$pathMethod + * @link https://github.com/doctrine-extensions/DoctrineExtensions/blob/main/doc/uploadable.md#uploadable-annotations-and-attributes + * + * @noinspection PhpUnused + */ + public function getFileDirectoryPath (string $globalFileDirectoryPath): string { + return $globalFileDirectoryPath . DIRECTORY_SEPARATOR . $this->owner->getId(); + } + /** + * @param array $fileInfo + * + * @return void + * + * @see \Gedmo\Mapping\Annotation\Uploadable::$callback + * @link https://github.com/doctrine-extensions/DoctrineExtensions/blob/main/doc/uploadable.md#uploadable-annotations-and-attributes + * + * @noinspection PhpUnused * + */ + public function onFileMove (array $fileInfo): void { + $this->fileName = $fileInfo['origFileName']; // Information absente de la doc mais bien alimentée + } } diff --git a/src/Entity/TEntityBase.php b/src/Entity/TEntityBase.php index 27d0e49..84c8ad7 100644 --- a/src/Entity/TEntityBase.php +++ b/src/Entity/TEntityBase.php @@ -6,7 +6,6 @@ use DateTimeInterface; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Gedmo\Mapping\Annotation as Gedmo; -use Gedmo\Mapping\Annotation\Timestampable; /** * Implementation for the base implementation of an entity: id, creation and last update date and time @@ -32,7 +31,7 @@ trait TEntityBase { * @var DateTimeInterface|null The last modification date and time */ #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: false)] - #[Timestampable(on: 'update')] + #[Gedmo\Timestampable(on: 'update')] private ?DateTimeInterface $lastModification = null; /** diff --git a/src/Entity/User.php b/src/Entity/User.php index cef1a0d..e532462 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -19,18 +19,18 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface { use TEntityBase; /** - * @var string|null The email + * @var string The email */ #[ORM\Column(length: 100, unique: true)] #[Assert\NotBlank] #[Assert\Email] - private ?string $email = null; + private string $email; /** - * @var string|null The hashed password + * @var string The hashed password */ - #[ORM\Column] + #[ORM\Column(length: 255)] #[Assert\NotBlank] - private ?string $password = null; + private string $password; /** * @var string|null The name