Przeglądaj źródła

fix remaining conflicts

Olivier Massot 3 lat temu
rodzic
commit
fdf8646e2e

+ 1 - 1
src/Service/Cron/Job/CleanTempFiles.php

@@ -6,7 +6,7 @@ use App\Repository\Access\AccessRepository;
 use App\Repository\Core\FileRepository;
 use App\Service\Cron\BaseCronJob;
 use App\Service\Cron\CronjobInterface;
-use App\Service\Storage\LocalStorage;
+use App\Service\File\Storage\LocalStorage;
 use App\Service\Utils\DatesUtils;
 use Doctrine\Common\Collections\Collection;
 use Doctrine\Common\Collections\Criteria;

+ 0 - 353
src/Service/Storage/LocalStorage.php

@@ -1,353 +0,0 @@
-<?php
-declare(strict_types=1);
-
-namespace App\Service\Storage;
-
-use ApiPlatform\Core\Api\IriConverterInterface;
-use App\ApiResources\DownloadRequest;
-use App\Entity\Access\Access;
-use App\Entity\Core\File;
-use App\Entity\Organization\Organization;
-use App\Entity\Person\Person;
-use App\Enum\Core\FileStatusEnum;
-use App\Enum\Core\FileTypeEnum;
-use App\Repository\Access\AccessRepository;
-use App\Service\Utils\Path;
-use App\Service\Utils\Uuid;
-use DateTime;
-use Doctrine\ORM\EntityManagerInterface;
-use Gaufrette\Filesystem;
-use JetBrains\PhpStorm\Pure;
-use Knp\Bundle\GaufretteBundle\FilesystemMap;
-use Mimey\MimeTypes;
-use RuntimeException;
-
-/**
- * Read and write files into the file storage
- */
-class LocalStorage implements FileStorageInterface
-{
-    /**
-     * Key of the gaufrette storage, as defined in config/packages/knp_gaufrette.yaml
-     */
-    protected const FS_KEY = 'storage';
-
-    protected Filesystem $filesystem;
-
-    public function __construct(
-        protected FilesystemMap $filesystemMap,
-        protected EntityManagerInterface $entityManager,
-        protected AccessRepository $accessRepository,
-        protected IriConverterInterface $iriConverter
-    )
-    {
-        $this->filesystem = $filesystemMap->get(static::FS_KEY);
-    }
-
-    /**
-     * Return true if the file exists in the file storage
-     *
-     * @param File $file
-     * @return bool
-     */
-    public function exists(File $file): bool {
-        return $this->filesystem->has($file->getSlug());
-    }
-
-    /**
-     * Get the IRI to download this file (eg: /api/download/1)
-     *
-     * @param File $file
-     * @return string
-     */
-    public function getDownloadIri(File $file): string
-    {
-        return $this->iriConverter->getItemIriFromResourceClass(
-            DownloadRequest::class,
-            ['fileId' => $file->getId()]
-        );
-    }
-
-    /**
-     * Lists all the non-temporary files of the given owner
-     *
-     * @param Organization|Access|Person $owner
-     * @param FileTypeEnum|null $type
-     * @return array
-     */
-    public function listByOwner (
-        Organization | Access | Person $owner,
-        ?FileTypeEnum $type = null
-    ): array {
-        return $this->filesystem->listKeys(
-            $this->getPrefix($owner, false, $type?->getValue())
-        );
-    }
-
-    /**
-     * Reads the given file and returns its content as a string
-     *
-     * @param File $file
-     * @return string
-     */
-    public function read(File $file): string
-    {
-        return $this->filesystem->read($file->getSlug());
-    }
-
-    /**
-     * Prepare a File record with a PENDING status.
-     * This record will hold all the data needed to create the file, except its content.
-     *
-     * @param Organization|Access|Person $owner Owner of the file, either an organization, a person or both (access)
-     * @param string $filename The file's name (mandatory)
-     * @param FileTypeEnum $type The type of the new file
-     * @param Access $createdBy Id of the access responsible for this creation
-     * @param bool $isTemporary Is it a temporary file that can be deleted after some time
-     * @param string|null $mimeType Mimetype of the file, if not provided, the method will try to guess it from its file name's extension
-     * @param string $visibility
-     * @param bool $flushFile Should the newly created file be flushed after having been persisted?
-     * @return File
-     */
-    public function prepareFile(
-        Organization | Access | Person $owner,
-        string $filename,
-        FileTypeEnum $type,
-        Access $createdBy,
-        bool $isTemporary = false,
-        string $visibility = 'NOBODY',
-        string $mimeType = null,
-        bool $flushFile = true
-    ): File
-    {
-        [$organization, $person] = $this->getOrganizationAndPersonFromOwner($owner);
-
-        $file = (new File())
-            ->setName($filename)
-            ->setOrganization($organization)
-            ->setPerson($person)
-            ->setSlug(null)
-            ->setType($type->getValue())
-            ->setVisibility($visibility)
-            ->setIsTemporaryFile($isTemporary)
-            ->setMimeType($mimeType ?? self::guessMimeTypeFromFilename($filename))
-            ->setCreateDate(new DateTime())
-            ->setCreatedBy($createdBy->getId())
-            ->setStatus(FileStatusEnum::PENDING()->getValue());
-
-        $this->entityManager->persist($file);
-
-        if ($flushFile) {
-            $this->entityManager->flush();
-        }
-
-        return $file;
-    }
-
-    /**
-     * Write the $content into the file storage and update the given File object's size, slug, status (READY)...
-     *
-     * @param File $file The file object that is about to be written
-     * @param string $content The content of the file
-     * @param Access $author The access responsible for the creation / update of the file
-     * @return File
-     */
-    public function writeFile(File $file, string $content, Access $author): File
-    {
-        if (empty($file->getName())) {
-            throw new RuntimeException('File has no filename');
-        }
-
-        $isNewFile = $file->getSlug() === null;
-        if ($isNewFile) {
-            // Try to get the Access owner from the organization_id and person_id
-            $access = null;
-            if ($file->getOrganization() !== null && $file->getPerson() !== null) {
-                $access = $this->accessRepository->findOneBy(
-                    ['organization' => $file->getOrganization(), 'person' => $file->getPerson()]
-                );
-            }
-
-            $prefix = $this->getPrefix(
-                $access ?? $file->getOrganization() ?? $file->getPerson(),
-                $file->getIsTemporaryFile(),
-                $file->getType()
-            );
-
-            $uid = date('Ymd_His') . '_' . Uuid::uuid(5);
-
-            $key = Path::join($prefix, $uid, $file->getName());
-        } else {
-            $key = $file->getSlug();
-        }
-
-        if (!$isNewFile && !$this->filesystem->has($key)) {
-            throw new RuntimeException('The file `' . $key . '` does not exist in the file storage');
-        }
-
-        $size = $this->filesystem->write($key, $content, true);
-
-        $file->setSize($size)
-             ->setStatus(FileStatusEnum::READY()->getValue());
-
-        if ($isNewFile) {
-            $file->setSlug($key)
-                 ->setCreateDate(new DateTime())
-                 ->setCreatedBy($author->getId());
-        } else {
-            $file->setUpdateDate(new DateTime())
-                 ->setUpdatedBy($author->getId());
-        }
-
-        $this->entityManager->flush();
-
-        return $file;
-    }
-
-    /**
-     * Convenient method to successively prepare and write a file
-     *
-     * @param Organization|Access|Person $owner
-     * @param string $filename
-     * @param FileTypeEnum $type
-     * @param string $content
-     * @param Access $author
-     * @param bool $isTemporary
-     * @param string|null $mimeType
-     * @param string $visibility
-     * @return File
-     */
-    public function makeFile (
-        Organization | Access | Person $owner,
-        string                         $filename,
-        FileTypeEnum                   $type,
-        string                         $content,
-        Access                         $author,
-        bool                           $isTemporary = false,
-        string                         $visibility = 'NOBODY',
-        string                         $mimeType = null
-    ): File
-    {
-        $file = $this->prepareFile(
-            $owner,
-            $filename,
-            $type,
-            $author,
-            $isTemporary,
-            $visibility,
-            $mimeType,
-            false
-        );
-
-        return $this->writeFile($file, $content, $author);
-    }
-
-    /**
-     * Delete the given file from the filesystem and update the status of the File
-     *
-     * @param File $file
-     * @param Access $author
-     * @return File
-     */
-    public function delete(File $file, Access $author): File
-    {
-        $deleted = $this->filesystem->delete($file->getSlug());
-
-        if (!$deleted) {
-            throw new RuntimeException('File `' . $file->getSlug() . '` could\'nt be deleted');
-        }
-
-        $file->setStatus(FileStatusEnum::DELETED()->getValue())
-             ->setSize(0)
-             ->setUpdatedBy($author->getId());
-
-        $this->entityManager->flush();
-
-        return $file;
-    }
-
-    /**
-     * Return the mimetype corresponding to the givent file extension
-     *
-     * @param string $ext
-     * @return string|null
-     */
-    public static function getMimeTypeFromExt(string $ext): string | null {
-        return (new MimeTypes)->getMimeType(ltrim($ext, '.'));
-    }
-
-    /**
-     * Try to guess the mimetype from the filename
-     *
-     * Return null if it did not manage to guess it.
-     *
-     * @param string $filename
-     * @return string|null
-     */
-    public static function guessMimeTypeFromFilename(string $filename): string | null {
-        $ext = pathinfo($filename, PATHINFO_EXTENSION);
-        if (empty($ext)) {
-            return null;
-        }
-        return self::getMimeTypeFromExt($ext);
-    }
-
-    /**
-     * If an organization owns the file, the prefix will be '(_temp_/)organization/{id}(/{type})'.
-     * If a person owns it, the prefix will be '(_temp_/)person/{id}(/{type})'
-     * If access owns it, the prefix will be '(_temp_/)organization/{organization_id}/{access_id}(/{type})'
-     *
-     * With {id} being the id of the organization or of the person.
-     *
-     * If the file is temporary, '_temp_/' is prepended to the prefix.
-     * If a file type is given, this type is appended to the prefix (low case)
-     *
-     * @param Organization|Access|Person $owner
-     * @param bool $isTemporary
-     * @param string|null $type
-     * @return string
-     */
-    protected function getPrefix(
-        Organization | Access | Person $owner,
-        bool $isTemporary,
-        string $type = null
-    ): string
-    {
-        if ($owner instanceof Access) {
-            $prefix = Path::join('organization', $owner->getOrganization()?->getId(), $owner->getId());
-        } else if ($owner instanceof Organization) {
-            $prefix = Path::join('organization', $owner->getId());
-        } else {
-            $prefix = Path::join('person', $owner->getId());
-        }
-
-        if ($isTemporary) {
-            $prefix = Path::join('temp', $prefix);
-        }
-
-        if ($type !== null && $type !== FileTypeEnum::NONE()->getValue()) {
-            $prefix = Path::join($prefix, strtolower($type));
-        }
-
-        return $prefix;
-    }
-
-    /**
-     * Return an array [$organization, $person] from a given owner
-     *
-     * @param Organization|Access|Person $owner
-     * @return array
-     */
-    #[Pure]
-    protected function getOrganizationAndPersonFromOwner(Organization | Access | Person $owner): array {
-        if ($owner instanceof Access) {
-            return [$owner->getOrganization(), $owner->getPerson()];
-        }
-
-        if ($owner instanceof Organization) {
-            return [$owner, null];
-        }
-
-        return [null, $owner];
-    }
-}