''])] private string $filename = ''; /** * @var Collection&Selectable */ #[ORM\OneToMany(mappedBy: 'objectVersion', targetEntity: StoredObjectPointInTime::class, cascade: ['persist', 'remove'], orphanRemoval: true)] private Collection&Selectable $pointInTimes; /** * Previous storedObjectVersion, from which the current stored object version is created. * * If null, the current stored object version is generated by other means. * * Those version may be associated with the same storedObject, or not. In this last case, that means that * the stored object's current version is created from another stored object version. */ #[ORM\ManyToOne(targetEntity: StoredObjectVersion::class)] private ?StoredObjectVersion $createdFrom = null; /** * List of stored object versions created from the current version. * * @var Collection */ #[ORM\OneToMany(mappedBy: 'createdFrom', targetEntity: StoredObjectVersion::class)] private Collection $children; public function __construct( /** * The stored object associated with this version. */ #[ORM\ManyToOne(targetEntity: StoredObject::class, inversedBy: 'versions')] #[ORM\JoinColumn(name: 'stored_object_id', nullable: false)] private StoredObject $storedObject, /** * The incremental version. */ #[ORM\Column(name: 'version', type: \Doctrine\DBAL\Types\Types::INTEGER, options: ['default' => 0])] private int $version = 0, /** * vector for encryption. * * @var int[] */ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON, name: 'iv')] private array $iv = [], /** * Key infos for document encryption. * * @var array */ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::JSON, name: 'key')] private array $keyInfos = [], /** * type of the document. */ #[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, name: 'type', options: ['default' => ''])] private string $type = '', ?string $filename = null, ) { $this->filename = $filename ?? self::generateFilename($this); $this->pointInTimes = new ArrayCollection(); $this->children = new ArrayCollection(); } public static function generateFilename(StoredObjectVersion $storedObjectVersion): string { try { $suffix = base_convert(bin2hex(random_bytes(8)), 16, 36); } catch (RandomException) { $suffix = uniqid(more_entropy: true); } return $storedObjectVersion->getStoredObject()->getPrefix().'/'.$suffix; } public function getFilename(): string { return $this->filename; } public function getId(): ?int { return $this->id; } public function getIv(): array { return $this->iv; } public function getKeyInfos(): array { return $this->keyInfos; } public function getStoredObject(): StoredObject { return $this->storedObject; } public function getType(): string { return $this->type; } public function getVersion(): int { return $this->version; } /** * @return Collection&Selectable */ public function getPointInTimes(): Selectable&Collection { return $this->pointInTimes; } public function hasPointInTimes(): bool { return $this->pointInTimes->count() > 0; } /** * @internal use @see{StoredObjectPointInTime} constructor instead */ public function addPointInTime(StoredObjectPointInTime $storedObjectPointInTime): self { if (!$this->pointInTimes->contains($storedObjectPointInTime)) { $this->pointInTimes->add($storedObjectPointInTime); } return $this; } public function removePointInTime(StoredObjectPointInTime $storedObjectPointInTime): self { if ($this->pointInTimes->contains($storedObjectPointInTime)) { $this->pointInTimes->removeElement($storedObjectPointInTime); } return $this; } public function getCreatedFrom(): ?StoredObjectVersion { return $this->createdFrom; } public function setCreatedFrom(?StoredObjectVersion $createdFrom): StoredObjectVersion { if (null === $createdFrom && null !== $this->createdFrom) { $this->createdFrom->removeChild($this); } $createdFrom?->addChild($this); $this->createdFrom = $createdFrom; return $this; } public function addChild(StoredObjectVersion $child): self { if (!$this->children->contains($child)) { $this->children->add($child); } return $this; } public function removeChild(StoredObjectVersion $child): self { $result = $this->children->removeElement($child); if (false === $result) { throw new \UnexpectedValueException('the child is not associated with the current stored object version'); } return $this; } public function isEncrypted(): bool { return ([] !== $this->getKeyInfos()) && ([] !== $this->getIv()); } }