199 lines
5.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\WopiBundle\Service\Wopi;
use ChampsLibres\WopiLib\Contract\Entity\Document;
use ChampsLibres\WopiLib\Contract\Service\DocumentLockManagerInterface;
use ChampsLibres\WopiLib\Contract\Service\DocumentManagerInterface;
use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Repository\StoredObjectRepository;
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
use Doctrine\ORM\EntityManagerInterface;
use loophp\psr17\Psr17Interface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\StreamInterface;
use Ramsey\Uuid\Uuid;
use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Mime\MimeTypes;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
final readonly class ChillDocumentManager implements DocumentManagerInterface
{
private RequestInterface $request;
public function __construct(
private DocumentLockManagerInterface $documentLockManager,
private EntityManagerInterface $entityManager,
HttpMessageFactoryInterface $httpMessageFactory,
private Psr17Interface $psr17,
RequestStack $requestStack,
private StoredObjectManagerInterface $storedObjectManager,
private StoredObjectRepository $storedObjectRepository
) {
$this->request = $httpMessageFactory->createRequest($requestStack->getCurrentRequest());
}
public function create(array $data): Document
{
/** @var StoredObject $document */
$document = (new ObjectNormalizer())->denormalize([], StoredObject::class);
// Mime types / extension handling.
$mimeTypes = new MimeTypes();
$mimeTypes->getMimeTypes($data['extension']);
$document->setType(reset($mimeTypes));
$document->setFilename($data['name']);
$this->entityManager->persist($document);
$this->entityManager->flush();
// TODO : Ask proper mapping.
// Available: basename, name, extension, content, size
$this->setContent($document, $data['content']);
return $document;
}
public function deleteLock(Document $document): void
{
if (false === $this->documentLockManager->deleteLock($document, $this->request)) {
throw new \RuntimeException('could not remove the lock');
}
}
/**
* @param string $documentFilename without extension !
*/
public function findByDocumentFilename(string $documentFilename): ?Document
{
return $this->storedObjectRepository->findOneBy(
[
'filename' => $documentFilename,
]
);
}
public function findByDocumentId(string $documentId): ?Document
{
return $this->storedObjectRepository->findOneBy(
[
'uuid' => Uuid::fromString($documentId),
]
);
}
/**
* @param StoredObject $document
*
* @return string the document filename with its extension
*/
public function getBasename(Document $document): string
{
$exts = (new MimeTypes())->getExtensions($document->getType());
if ([] === $exts) {
throw new \Error('Unknown mimetype for stored document.');
}
return sprintf('%s.%s', $document->getFilename(), reset($exts));
}
/**
* @param StoredObject $document
*/
public function getCreationDate(Document $document): \DateTimeInterface
{
return $document->getCreatedAt() ?? new \DateTimeImmutable('now');
}
/**
* @param StoredObject $document
*/
public function getDocumentId(Document $document): string
{
return (string) $document->getUuid();
}
/**
* @param StoredObject $document
*/
public function getLastModifiedDate(Document $document): \DateTimeInterface
{
return $this->storedObjectManager->getLastModified($document);
}
public function getLock(Document $document): string
{
return $this->documentLockManager->getLock($document, $this->request);
}
public function getSha256(Document $document): string
{
return base64_encode(hash('sha256', $this->getContent($document)));
}
public function getSize(Document $document): int
{
return \strlen($this->getContent($document));
}
public function getVersion(Document $document): string
{
// TODO ?
return '0';
}
public function hasLock(Document $document): bool
{
return $this->documentLockManager->hasLock($document, $this->request);
}
public function lock(Document $document, string $lock): void
{
$this->documentLockManager->setLock($document, $lock, $this->request);
}
public function read(Document $document): StreamInterface
{
return $this
->psr17
->createStream($this->getContent($document));
}
public function remove(Document $document): void
{
throw new \RuntimeException('this is not implemented and should not happens');
}
public function rename(Document $document, string $requestedName): void
{
throw new \RuntimeException('this is not implemented and should not happens');
}
public function write(Document $document, array $properties = []): void
{
$this->setContent($document, $properties['content']);
}
private function getContent(StoredObject $storedObject): string
{
return $this->storedObjectManager->read($storedObject);
}
private function setContent(StoredObject $storedObject, string $content): void
{
$this->storedObjectManager->write($storedObject, $content);
}
}