Julien Fastré 1b21cd6c33
Add StoredObjectPointInTime entity and related functionality
Implemented a new StoredObjectPointInTime entity to manage snapshots of stored objects. This includes related migrations, enum for reasons, repository, and integration with StoredObjectVersion.
2024-09-10 14:29:19 +02:00

174 lines
4.8 KiB
PHP

<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\DocStoreBundle\Entity;
use Chill\MainBundle\Doctrine\Model\TrackCreationInterface;
use Chill\MainBundle\Doctrine\Model\TrackCreationTrait;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Selectable;
use Doctrine\ORM\Mapping as ORM;
use Random\RandomException;
/**
* Store each version of StoredObject's.
*
* A version should not be created manually: use the method @see{StoredObject::registerVersion} instead.
*/
#[ORM\Entity]
#[ORM\Table('chill_doc.stored_object_version')]
#[ORM\UniqueConstraint(name: 'chill_doc_stored_object_version_unique_by_object', columns: ['stored_object_id', 'version'])]
class StoredObjectVersion implements TrackCreationInterface
{
use TrackCreationTrait;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::INTEGER)]
private ?int $id = null;
/**
* filename of the version in the stored object.
*/
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::TEXT, nullable: false, options: ['default' => ''])]
private string $filename = '';
/**
* @var Collection<int, StoredObjectPointInTime>&Selectable<int, StoredObjectPointInTime>
*/
#[ORM\OneToMany(mappedBy: 'objectVersion', targetEntity: StoredObjectPointInTime::class, cascade: ['persist', 'remove'], orphanRemoval: true)]
private Collection&Selectable $pointInTimes;
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();
}
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<int, StoredObjectPointInTime>&Selectable<int, StoredObjectPointInTime>
*/
public function getPointInTimes(): Selectable&Collection
{
return $this->pointInTimes;
}
public function hasPointInTimes(): bool
{
return $this->pointInTimes->count() > 0;
}
/**
* @return $this
*
* @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;
}
}