- <?php
- /*
-  * This file is part of Sulu.
-  *
-  * (c) Sulu GmbH
-  *
-  * This source file is subject to the MIT license that is bundled
-  * with this source code in the file LICENSE.
-  */
- namespace Sulu\Bundle\MediaBundle\Media\Storage;
- use Psr\Log\LoggerInterface;
- use Psr\Log\NullLogger;
- use Sulu\Bundle\MediaBundle\Media\Exception\FilenameAlreadyExistsException;
- use Symfony\Component\Filesystem\Exception\IOException;
- use Symfony\Component\Filesystem\Filesystem;
- class LocalStorage implements StorageInterface
- {
-     /**
-      * @var string
-      */
-     private $uploadPath;
-     /**
-      * @var int
-      */
-     private $segments;
-     /**
-      * @var Filesystem
-      */
-     private $filesystem;
-     /**
-      * @var LoggerInterface
-      */
-     private $logger;
-     public function __construct(
-         string $uploadPath,
-         string $segments,
-         Filesystem $filesystem,
-         ?LoggerInterface $logger = null
-     ) {
-         $this->uploadPath = $uploadPath;
-         $this->segments = $segments;
-         $this->filesystem = $filesystem;
-         $this->logger = $logger ?: new NullLogger();
-     }
-     public function save(string $tempPath, string $fileName, array $storageOptions = []): array
-     {
-         if (!\array_key_exists('segment', $storageOptions)) {
-             $storageOptions['segment'] = \sprintf('%0' . \strlen($this->segments) . 'd', \rand(1, $this->segments));
-         }
-         $this->createDirectories($storageOptions);
-         $directory = $this->getStorageOption($storageOptions, 'directory');
-         $segment = $this->getStorageOption($storageOptions, 'segment');
-         $parentPath = $this->getFilesystemPath($directory, $segment);
-         $storageOptions['fileName'] = $this->getUniqueFileName($parentPath, $fileName);
-         $filePath = $this->getFilesystemPath($directory, $segment, $storageOptions['fileName']);
-         $this->logger->debug('Try to copy File "' . $tempPath . '" to "' . $filePath . '"');
-         if ($this->filesystem->exists($filePath)) {
-             throw new FilenameAlreadyExistsException($filePath);
-         }
-         $this->filesystem->copy($tempPath, $filePath);
-         return $storageOptions;
-     }
-     public function load(array $storageOptions)
-     {
-         return \fopen($this->getPath($storageOptions), 'r');
-     }
-     public function getPath(array $storageOptions): string
-     {
-         $directory = $this->getStorageOption($storageOptions, 'directory');
-         $segment = $this->getStorageOption($storageOptions, 'segment');
-         $fileName = $this->getStorageOption($storageOptions, 'fileName');
-         if (!$segment || !$fileName) {
-             throw new \RuntimeException();
-         }
-         return $this->getFilesystemPath($directory, $segment, $fileName);
-     }
-     public function getType(array $storageOptions): string
-     {
-         return self::TYPE_LOCAL;
-     }
-     public function move(array $sourceStorageOptions, array $targetStorageOptions): array
-     {
-         $this->createDirectories($targetStorageOptions);
-         $targetDirectory = $this->getStorageOption($targetStorageOptions, 'directory');
-         $targetSegment = $this->getStorageOption($targetStorageOptions, 'segment');
-         $targetFileName = $this->getStorageOption($targetStorageOptions, 'fileName');
-         $targetParentPath = $this->getFilesystemPath($targetDirectory, $targetSegment);
-         $targetStorageOptions['fileName'] = $this->getUniqueFileName($targetParentPath, $targetFileName);
-         $targetPath = $this->getPath($targetStorageOptions);
-         if ($this->filesystem->exists($targetPath)) {
-             throw new FilenameAlreadyExistsException($targetPath);
-         }
-         $this->filesystem->rename($this->getPath($sourceStorageOptions), $targetPath);
-         return $targetStorageOptions;
-     }
-     public function remove(array $storageOptions): void
-     {
-         try {
-             $this->filesystem->remove($this->getPath($storageOptions));
-         } catch (IOException $ex) {
-         }
-     }
-     /**
-      * Get a unique filename in path.
-      */
-     private function getUniqueFileName(string $parentPath, string $fileName, int $counter = 0): string
-     {
-         $newFileName = $fileName;
-         if ($counter > 0) {
-             $fileNameParts = \explode('.', $fileName, 2);
-             $newFileName = $fileNameParts[0] . '-' . $counter;
-             if (isset($fileNameParts[1])) {
-                 $newFileName .= '.' . $fileNameParts[1];
-             }
-         }
-         $filePath = \rtrim($parentPath, '/') . '/' . \ltrim($newFileName, '/');
-         $this->logger->debug('Check FilePath: ' . $filePath);
-         if (!$this->filesystem->exists($filePath)) {
-             return $newFileName;
-         }
-         ++$counter;
-         return $this->getUniqueFileName($parentPath, $fileName, $counter);
-     }
-     private function getFilesystemPath(?string $directory, ?string $segment = null, ?string $fileName = null): string
-     {
-         return \implode('/', \array_filter([$this->uploadPath, $directory, $segment, $fileName]));
-     }
-     /**
-      * @param array<string, string|null> $storageOptions
-      */
-     private function getStorageOption(array $storageOptions, string $key): ?string
-     {
-         return \array_key_exists($key, $storageOptions) ? $storageOptions[$key] : null;
-     }
-     /**
-      * @param array<string, string|null> $storageOptions
-      */
-     private function createDirectories(array $storageOptions): void
-     {
-         $directory = $this->getStorageOption($storageOptions, 'directory');
-         $segment = $this->getStorageOption($storageOptions, 'segment');
-         $segmentPath = $this->getFilesystemPath($directory, $segment);
-         if (!$this->filesystem->exists($segmentPath)) {
-             $this->logger->debug('Try Create Folder: ' . $segmentPath);
-             $this->filesystem->mkdir($segmentPath, 0777);
-         }
-     }
- }
-