src/Entity/Order/OrderItemPhoto.php line 32
<?php/** This file is part of the Pellipop project.** (c) Mobizel** For the full copyright and license information, please view the LICENSE* file that was distributed with this source code.*/declare(strict_types=1);namespace App\Entity\Order;use App\Entity\Media\File;use App\OrderItemPhotoStates;use App\Repository\Order\OrderItemPhotoRepository;use App\Validator\Constraints\OrderItemPhotosMaxCount;use Doctrine\ORM\Mapping as ORM;use Monofony\Contracts\Core\Model\Media\FileInterface;use Symfony\Component\Serializer\Annotation\Groups;use Symfony\Component\Validator\Constraints as Assert;use Vich\UploaderBundle\Mapping\Annotation as Vich;/*** @Vich\Uploadable*/#[ORM\Entity(repositoryClass: OrderItemPhotoRepository::class)]#[ORM\Table(name: 'app_order_item_photo')]#[OrderItemPhotosMaxCount()]class OrderItemPhoto extends File implements FileInterface{/*** @Vich\UploadableField(mapping="order_item_photo", fileNameProperty="path")*/#[Assert\Image(maxSize: '100M')]protected ?\SplFileInfo $file = null;#[ORM\ManyToOne(inversedBy: 'photos')]#[ORM\JoinColumn(nullable: false)]private ?OrderItem $orderItem = null;#[ORM\Column(length: 255, nullable: true)]#[Groups(['image:read'])]private ?string $fujiHash = null;#[ORM\Column(length: 20)]#[Groups(['image:read'])]private ?string $state = null;#[ORM\Column(length: 1000, nullable: true)]#[Groups(['image:read'])]private ?string $tag = null;/*** Centre du cadrage utilisateur, normalisé (0..1) dans l'image originale.* Null = pas de cadrage utilisateur transmis (anciennes commandes) : fallback sur le* recadrage centré automatique existant (voir ResizePhotoFileModifier).*/#[ORM\Column(type: 'float', nullable: true)]#[Groups(['image:read'])]private ?float $cropOffsetX = null;#[ORM\Column(type: 'float', nullable: true)]#[Groups(['image:read'])]private ?float $cropOffsetY = null;/*** Zoom du cadrage utilisateur : 1.0 = cadrage "ajusté" (le plus grand rectangle au ratio* impression centré sur cropOffsetX/Y), > 1.0 = recadrage plus serré.*/#[ORM\Column(type: 'float', nullable: true)]#[Groups(['image:read'])]private ?float $cropZoom = null;/*** Rotation par quart de tour appliquée avant le cadrage : 0, 1, 2 ou 3 (× 90°).*/#[ORM\Column(type: 'smallint', nullable: true)]#[Groups(['image:read'])]private ?int $cropRotationQuarterTurns = null;/*** Vrai si le cadre d'impression est pivoté (portrait <-> paysage) indépendamment de* cropRotationQuarterTurns — permet un cadre paysage sur une photo portrait (ou l'inverse)* sans faire pivoter les pixels de l'image elle-même.*/#[ORM\Column(type: 'boolean', nullable: true)]#[Groups(['image:read'])]private ?bool $cropFrameSwapped = null;/*** Nom de fichier d'une copie de la photo originale, prise juste avant le tout premier* recadrage (voir ResizePhotoFileModifier::resize()) — uniquement pour l'affichage* avant/après dans le BO (OrderItemPhotoComparisonController). `path` reste le fichier* "actuel" envoyé à Fuji, inchangé : ce champ n'affecte jamais l'envoi. Reste `null` pour les* photos déjà traitées avant l'ajout de cette fonctionnalité (original perdu, écrasé en place* par l'ancien comportement) — le BO doit gérer ce cas en affichant "original non disponible".*/#[ORM\Column(type: 'string', nullable: true)]#[Groups(['image:read'])]private ?string $originalPath = null;public function __construct(){$this->state = OrderItemPhotoStates::STATE_NEW;parent::__construct();}public function getOrderItem(): ?OrderItem{return $this->orderItem;}public function setOrderItem(?OrderItem $orderItem): self{$this->orderItem = $orderItem;return $this;}public function getFujiHash(): ?string{return $this->fujiHash;}public function setFujiHash(?string $fujiHash): self{$this->fujiHash = $fujiHash;return $this;}public function getState(): ?string{return $this->state;}public function setState(string $state): self{$this->state = $state;return $this;}public function getTag(): ?string{return $this->tag;}public function setTag(?string $tag): void{$this->tag = $tag;}public function getCropOffsetX(): ?float{return $this->cropOffsetX;}public function setCropOffsetX(?float $cropOffsetX): void{$this->cropOffsetX = $cropOffsetX;}public function getCropOffsetY(): ?float{return $this->cropOffsetY;}public function setCropOffsetY(?float $cropOffsetY): void{$this->cropOffsetY = $cropOffsetY;}public function getCropZoom(): ?float{return $this->cropZoom;}public function setCropZoom(?float $cropZoom): void{$this->cropZoom = $cropZoom;}public function getCropRotationQuarterTurns(): ?int{return $this->cropRotationQuarterTurns;}public function setCropRotationQuarterTurns(?int $cropRotationQuarterTurns): void{$this->cropRotationQuarterTurns = $cropRotationQuarterTurns;}public function getCropFrameSwapped(): ?bool{return $this->cropFrameSwapped;}public function setCropFrameSwapped(?bool $cropFrameSwapped): void{$this->cropFrameSwapped = $cropFrameSwapped;}public function getOriginalPath(): ?string{return $this->originalPath;}public function setOriginalPath(?string $originalPath): void{$this->originalPath = $originalPath;}/*** Vrai si l'app a transmis un cadrage utilisateur complet pour cette photo.* Si faux, ResizePhotoFileModifier doit garder le recadrage centré automatique existant.*/public function hasUserCrop(): bool{return null !== $this->cropOffsetX&& null !== $this->cropOffsetY&& null !== $this->cropZoom;}}