Skip to content

Commit

Permalink
Add ImageableInterface, PdfInterface and their trait to demonstrate h…
Browse files Browse the repository at this point in the history
…ow to properly configure VichUploader annotations/attributes
  • Loading branch information
mathieu-ducrot committed Jun 28, 2024
1 parent f3d9098 commit d3d78aa
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
CHANGELOG for 1.x
===================
## v1.9.0 - (2024-06-XX)
### Added
- `ImageableInterface`, `PdfInterface` and their trait to demonstrate how to properly configure VichUploader annotations/attributes
- `MimeTypesUtils` helper for constraints mimeTypes check

## v1.8.0 - (2024-06-25)

**Add Entity json History feature**
Expand Down
36 changes: 36 additions & 0 deletions src/Entity/ImageableInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Smart\CoreBundle\Entity;

use Symfony\Component\HttpFoundation\File\File;

/**
* @author Mathieu Ducrot <[email protected]>
*/
interface ImageableInterface
{
public const IMAGE_MAPPING = 'image';
public const IMAGE_MAX_SIZE = '8M';
public const IMAGE_MAX_WIDTH = '1000';
public const IMAGE_MAX_HEIGHT = '1000';

public function hasImage(): bool;

public function getFormattedImageSize(): ?string;

public function setImageFile(File|false|null $file = null): void;

public function getImageFile(): File|false|null;

public function getImageOriginalName(): ?string;

public function setImageOriginalName(?string $name): self;

public function getImageName(): ?string;

public function setImageName(?string $name): self;

public function getImageSize(): ?float;

public function setImageSize(?float $size): self;
}
129 changes: 129 additions & 0 deletions src/Entity/ImageableTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

namespace Smart\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Smart\CoreBundle\Utils\MathUtils;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Uid\Uuid;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Validator\Constraints as Assert;

trait ImageableTrait
{
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property to use in form type.
* If the project use annotation then the entity using this trait must add the following :
* @Vich\UploadableField(mapping="%mapping_name%", fileNameProperty="imageName", size="imageSize")
* @Assert\Image(maxSize=self::IMAGE_MAX_SIZE, maxWidth=self::IMAGE_MAX_WIDTH, maxHeight=self::IMAGE_MAX_HEIGHT)
* protected File|false|null $imageFile = null;
*/
#[Vich\UploadableField(mapping: self::IMAGE_MAPPING, fileNameProperty: "imageName", size:"imageSize")]
#[Assert\Image(maxSize: self::IMAGE_MAX_SIZE, maxWidth: self::IMAGE_MAX_WIDTH, maxHeight: self::IMAGE_MAX_HEIGHT)]
protected File|false|null $imageFile = null;

/**
* Original name of the uploaded image
* @ORM\Column(nullable=true)
*/
#[ORM\Column(nullable: true)]
protected ?string $imageOriginalName = null;

/**
* Image name based on the imageOriginalName slug concatenated with a hash
* @ORM\Column(nullable=true)
*/
#[ORM\Column(nullable: true)]
protected ?string $imageName = null;

/**
* @ORM\Column(nullable=true)
*/
#[ORM\Column(nullable: true)]
protected ?float $imageSize = null;

/**
* @ORM\Column(nullable=true)
*/
#[ORM\Column(nullable: true)]
protected ?\DateTimeImmutable $imageUpdatedAt = null;

public function hasImage(): bool
{
return $this->imageName !== null;
}

public function getFormattedImageSize(): ?string
{
$size = $this->getImageSize();
if ($size === null) {
return null;
}

return MathUtils::formatBytes($size);
}

/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*/
public function setImageFile(File|false|null $file = null): void
{
$this->imageFile = $file;

if ($file instanceof UploadedFile) {
$this->imageOriginalName = $file->getClientOriginalName();
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->imageUpdatedAt = new \DateTimeImmutable();
if ($this instanceof UuidInterface && $this->getUuid() === null) {
$this->setUuid(Uuid::v7());
}
}
}

public function getImageFile(): File|false|null
{
return $this->imageFile;
}

public function getImageOriginalName(): ?string
{
return $this->imageOriginalName;
}

public function setImageOriginalName(?string $name): self
{
$this->imageOriginalName = $name;

return $this;
}

public function getImageName(): ?string
{
return $this->imageName;
}

public function setImageName(?string $name): self
{
$this->imageName = $name;

return $this;
}

public function getImageSize(): ?float
{
return $this->imageSize;
}

public function setImageSize(?float $size): self
{
$this->imageSize = $size;

return $this;
}
}
34 changes: 34 additions & 0 deletions src/Entity/PdfInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Smart\CoreBundle\Entity;

use Symfony\Component\HttpFoundation\File\File;

/**
* @author Mathieu Ducrot <[email protected]>
*/
interface PdfInterface
{
public const PDF_MAPPING = 'pdf';
public const PDF_MAX_SIZE = '20M';

public function hasPdf(): bool;

public function getFormattedPdfSize(): ?string;

public function setPdfFile(File|false|null $file = null): void;

public function getPdfFile(): File|false|null;

public function getPdfOriginalName(): ?string;

public function setPdfOriginalName(?string $name): self;

public function getPdfName(): ?string;

public function setPdfName(?string $name): self;

public function getPdfSize(): ?float;

public function setPdfSize(?float $size): self;
}
130 changes: 130 additions & 0 deletions src/Entity/PdfTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

namespace Smart\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Smart\CoreBundle\Utils\MathUtils;
use Smart\CoreBundle\Utils\MimeTypesUtils;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Uid\Uuid;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Validator\Constraints as Assert;

trait PdfTrait
{
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property to use in form type.
* If the project use annotation then the entity using this trait must add the following :
* @Vich\UploadableField(mapping="%mapping_name%", fileNameProperty="pdfName", size="pdfSize")
* @Assert\File(maxSize=self::PDF_MAX_SIZE, mimeTypes=MimeTypesUtils::PDF)
* protected File|false|null $pdfFile = null;
*/
#[Vich\UploadableField(mapping: self::PDF_MAPPING, fileNameProperty: "pdfName", size:"pdfSize")]
#[Assert\File(maxSize: self::PDF_MAX_SIZE, mimeTypes: MimeTypesUtils::PDF)]
protected File|false|null $pdfFile = null;

/**
* Original name of the uploaded pdf
* @ORM\Column(nullable=true)
*/
#[ORM\Column(nullable: true)]
protected ?string $pdfOriginalName = null;

/**
* Pdf name based on the pdfOriginalName slug concatenated with a hash
* @ORM\Column(nullable=true)
*/
#[ORM\Column(nullable: true)]
protected ?string $pdfName = null;

/**
* @ORM\Column(nullable=true)
*/
#[ORM\Column(nullable: true)]
protected ?float $pdfSize = null;

/**
* @ORM\Column(nullable=true)
*/
#[ORM\Column(nullable: true)]
protected ?\DateTimeImmutable $pdfUpdatedAt = null;

public function hasPdf(): bool
{
return $this->pdfName !== null;
}

public function getFormattedPdfSize(): ?string
{
$size = $this->getPdfSize();
if ($size === null) {
return null;
}

return MathUtils::formatBytes($size);
}

/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*/
public function setPdfFile(File|false|null $file = null): void
{
$this->pdfFile = $file;

if ($file instanceof UploadedFile) {
$this->pdfOriginalName = $file->getClientOriginalName();
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->pdfUpdatedAt = new \DateTimeImmutable();
if ($this instanceof UuidInterface && $this->getUuid() === null) {
$this->setUuid(Uuid::v7());
}
}
}

public function getPdfFile(): File|false|null
{
return $this->pdfFile;
}

public function getPdfOriginalName(): ?string
{
return $this->pdfOriginalName;
}

public function setPdfOriginalName(?string $name): self
{
$this->pdfOriginalName = $name;

return $this;
}

public function getPdfName(): ?string
{
return $this->pdfName;
}

public function setPdfName(?string $name): self
{
$this->pdfName = $name;

return $this;
}

public function getPdfSize(): ?float
{
return $this->pdfSize;
}

public function setPdfSize(?float $size): self
{
$this->pdfSize = $size;

return $this;
}
}
12 changes: 12 additions & 0 deletions src/Entity/UuidInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Smart\CoreBundle\Entity;

use Symfony\Component\Uid\Uuid;

interface UuidInterface
{
public function getUuid(): ?Uuid; // @phpstan-ignore-line

public function setUuid(?Uuid $uuid): static; // @phpstan-ignore-line
}
28 changes: 28 additions & 0 deletions src/Entity/UuidTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Smart\CoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;

trait UuidTrait
{
/**
* @ORM\Column(type: 'uuid', unique=true, nullable=true)
*/
#[ORM\Column(type: UuidType::NAME, unique: true, nullable: true)]
private ?Uuid $uuid = null;

public function getUuid(): ?Uuid
{
return $this->uuid;
}

public function setUuid(?Uuid $uuid): static
{
$this->uuid = $uuid;

return $this;
}
}
11 changes: 11 additions & 0 deletions src/Utils/MimeTypesUtils.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Smart\CoreBundle\Utils;

/**
* @author Mathieu Ducrot <[email protected]>
*/
class MimeTypesUtils
{
public const PDF = ['application/pdf', 'application/acrobat', 'application/nappdf', 'application/x-pdf', 'image/pdf'];
}

0 comments on commit d3d78aa

Please sign in to comment.