An error occurred while loading the file. Please try again.
-
Cresson Remi authoredbed917ee
<?php declare(strict_types=1);
/*
* Copyright (C) 2015-2018 IRSTEA
* All rights reserved.
*/
namespace Irstea\FileUploadBundle\Service;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Gaufrette\Filesystem;
use Gaufrette\StreamMode;
use InvalidArgumentException;
use Irstea\FileUploadBundle\Entity\UploadedFile;
use Irstea\FileUploadBundle\Event\FileUploadCompleteEvent;
use Irstea\FileUploadBundle\Exception\RejectedFileException;
use Irstea\FileUploadBundle\FileUploadEvents;
use Irstea\FileUploadBundle\Model\FileManagerInterface;
use Irstea\FileUploadBundle\Model\UploadedFileInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
use Rhumsaa\Uuid\Uuid;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Class FileManager.
*/
final class FileManager implements FileManagerInterface
{
/**
* @var Filesystem
*/
private $filesystem;
/**
* @var EventDispatcherInterface
*/
private $eventDispatcher;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var EntityManagerInterface
*/
private $entityManager;
/**
* @var EntityRepository
*/
private $repository;
/**
* FileManager constructor.
*
* @param Filesystem $filesystem
* @param EventDispatcherInterface $eventDispatcher
* @param RegistryInterface $doctrine
* @param string $entityClass
* @param LoggerInterface $logger
*/
public function __construct(
Filesystem $filesystem,
EventDispatcherInterface $eventDispatcher,
RegistryInterface $doctrine,
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
string $entityClass,
LoggerInterface $logger = null
) {
$this->filesystem = $filesystem;
$this->eventDispatcher = $eventDispatcher;
$this->logger = $logger ?: new NullLogger();
$this->entityManager = $doctrine->getEntityManagerForClass($entityClass);
$this->repository = $this->entityManager->getRepository($entityClass);
}
/**
* {@inheritdoc}
*/
public function create(string $filename, int $size, string $mimeType, int $lastModified = null): UploadedFileInterface
{
$file = new UploadedFile();
$file->setFilesystem($this->filesystem);
$file
->setDisplayName($filename)
->setMetadata(
[
'client' => [
'filename' => $filename,
'size' => $size,
'mimeType' => $mimeType,
'lastModified' => $lastModified,
],
]
);
$this->entityManager->persist($file);
$this->entityManager->flush();
$this->logger->log(LogLevel::INFO, 'File created', ['file' => $file]);
return $file;
}
/**
* {@inheritdoc}
*/
public function duplicate(UploadedFileInterface $original): UploadedFileInterface
{
if (!$original->isValid()) {
throw new InvalidArgumentException('Impossible de dupliquer le fichier ' . $original->getId() . ' car il est invalide !');
}
$new = new UploadedFile();
$metadata = $original->getMetadata();
if (!isset($metadata['duplicateOf'])) {
$metadata['duplicateOf'] = [$original->getId()];
} else {
array_unshift($metadata['duplicateOf'], $original->getId());
}
$new->setFilesystem($this->filesystem);
$new
->setMetadata($metadata)
->setDisplayName($original->getDisplayName())
->setDescription($original->getDescription())
->setMimeType($original->getMimeType())
->setChecksum($original->getChecksum())
->setSize($original->getSize());
$stream = $this->filesystem->createStream($new->getPath());
$stream->open(new StreamMode('cb'));
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
$original->copyTo($stream->cast(STREAM_CAST_AS_STREAM));
$stream->close();
$this->entityManager->persist($new);
return $new;
}
/**
* {@inheritdoc}
*/
public function delete(UploadedFileInterface $file): void
{
$this->entityManager->remove($file);
$this->entityManager->flush();
$this->logger->log(LogLevel::INFO, 'File deleted', ['file' => $file]);
}
/**
* {@inheritdoc}
*/
public function get($uuid): ?UploadedFileInterface
{
if (!$uuid) {
return null;
}
if (!is_string($uuid) || !Uuid::isValid($uuid)) {
throw new InvalidArgumentException(sprintf('Identifiant invalide: %s', (string) $uuid));
}
/* @noinspection PhpUndefinedMethodInspection */
return $this->repository->findOneById($uuid);
}
/**
* {@inheritdoc}
*/
public function completed(UploadedFileInterface $file): void
{
$path = $file->getPath();
$filesystem = $this->filesystem;
$file
->setChecksum($filesystem->checksum($path))
->setSize($filesystem->size($path))
->setMimeType($filesystem->mimeType($path))
->setEtat(UploadedFileInterface::ETAT_ORPHELIN);
$this->entityManager->persist($file);
try {
$this->eventDispatcher->dispatch(FileUploadEvents::UPLOAD_COMPLETE, new FileUploadCompleteEvent($file));
$this->entityManager->flush();
$this->logger->log(LogLevel::INFO, 'File completed', ['file' => $file]);
} catch (RejectedFileException $ex) {
$file->setEtat(UploadedFileInterface::ETAT_REJETE);
$this->entityManager->flush();
$this->logger->log(LogLevel::WARNING, 'File rejected', ['file' => $file, 'exception' => $ex]);
throw $ex;
}
}
/**
* {@inheritdoc}
*/
public function findGarbage(): array
211212213214215216217218219220221222223224225226227228229230231232233234235
{
$files = $this->repository->findBy(['etat' => [UploadedFileInterface::ETAT_EN_COURS, UploadedFileInterface::ETAT_ORPHELIN]]);
$limit = new DateTime('now');
$limit->modify('- 1 hour');
return array_filter(
$files,
function (UploadedFileInterface $file) use ($limit) {
$mtime = $file->getLastModified();
return $mtime === null || $mtime < $limit;
}
);
}
/**
* {@inheritdoc}
*/
public function findFilesToValidate(): array
{
return $this->repository->findBy(['etat' => [UploadedFileInterface::ETAT_ORPHELIN, UploadedFileInterface::ETAT_NORMAL]]);
}
}