Forked from HYCAR-Hydro / airGR
Source project has a limited visibility.
FileManager.php 6.63 KiB
<?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]]); } }