vendor/sulu/sulu/src/Sulu/Bundle/MediaBundle/Media/Storage/LocalStorage.php line 78

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Sulu.
  4.  *
  5.  * (c) Sulu GmbH
  6.  *
  7.  * This source file is subject to the MIT license that is bundled
  8.  * with this source code in the file LICENSE.
  9.  */
  10. namespace Sulu\Bundle\MediaBundle\Media\Storage;
  11. use Psr\Log\LoggerInterface;
  12. use Psr\Log\NullLogger;
  13. use Sulu\Bundle\MediaBundle\Media\Exception\FilenameAlreadyExistsException;
  14. use Symfony\Component\Filesystem\Exception\IOException;
  15. use Symfony\Component\Filesystem\Filesystem;
  16. class LocalStorage implements StorageInterface
  17. {
  18.     /**
  19.      * @var string
  20.      */
  21.     private $uploadPath;
  22.     /**
  23.      * @var int
  24.      */
  25.     private $segments;
  26.     /**
  27.      * @var Filesystem
  28.      */
  29.     private $filesystem;
  30.     /**
  31.      * @var LoggerInterface
  32.      */
  33.     private $logger;
  34.     public function __construct(
  35.         string $uploadPath,
  36.         string $segments,
  37.         Filesystem $filesystem,
  38.         ?LoggerInterface $logger null
  39.     ) {
  40.         $this->uploadPath $uploadPath;
  41.         $this->segments $segments;
  42.         $this->filesystem $filesystem;
  43.         $this->logger $logger ?: new NullLogger();
  44.     }
  45.     public function save(string $tempPathstring $fileName, array $storageOptions = []): array
  46.     {
  47.         if (!\array_key_exists('segment'$storageOptions)) {
  48.             $storageOptions['segment'] = \sprintf('%0' \strlen($this->segments) . 'd'\rand(1$this->segments));
  49.         }
  50.         $this->createDirectories($storageOptions);
  51.         $directory $this->getStorageOption($storageOptions'directory');
  52.         $segment $this->getStorageOption($storageOptions'segment');
  53.         $parentPath $this->getFilesystemPath($directory$segment);
  54.         $storageOptions['fileName'] = $this->getUniqueFileName($parentPath$fileName);
  55.         $filePath $this->getFilesystemPath($directory$segment$storageOptions['fileName']);
  56.         $this->logger->debug('Try to copy File "' $tempPath '" to "' $filePath '"');
  57.         if ($this->filesystem->exists($filePath)) {
  58.             throw new FilenameAlreadyExistsException($filePath);
  59.         }
  60.         $this->filesystem->copy($tempPath$filePath);
  61.         return $storageOptions;
  62.     }
  63.     public function load(array $storageOptions)
  64.     {
  65.         return \fopen($this->getPath($storageOptions), 'r');
  66.     }
  67.     public function getPath(array $storageOptions): string
  68.     {
  69.         $directory $this->getStorageOption($storageOptions'directory');
  70.         $segment $this->getStorageOption($storageOptions'segment');
  71.         $fileName $this->getStorageOption($storageOptions'fileName');
  72.         if (!$segment || !$fileName) {
  73.             throw new \RuntimeException();
  74.         }
  75.         return $this->getFilesystemPath($directory$segment$fileName);
  76.     }
  77.     public function getType(array $storageOptions): string
  78.     {
  79.         return self::TYPE_LOCAL;
  80.     }
  81.     public function move(array $sourceStorageOptions, array $targetStorageOptions): array
  82.     {
  83.         $this->createDirectories($targetStorageOptions);
  84.         $targetDirectory $this->getStorageOption($targetStorageOptions'directory');
  85.         $targetSegment $this->getStorageOption($targetStorageOptions'segment');
  86.         $targetFileName $this->getStorageOption($targetStorageOptions'fileName');
  87.         $targetParentPath $this->getFilesystemPath($targetDirectory$targetSegment);
  88.         $targetStorageOptions['fileName'] = $this->getUniqueFileName($targetParentPath$targetFileName);
  89.         $targetPath $this->getPath($targetStorageOptions);
  90.         if ($this->filesystem->exists($targetPath)) {
  91.             throw new FilenameAlreadyExistsException($targetPath);
  92.         }
  93.         $this->filesystem->rename($this->getPath($sourceStorageOptions), $targetPath);
  94.         return $targetStorageOptions;
  95.     }
  96.     public function remove(array $storageOptions): void
  97.     {
  98.         try {
  99.             $this->filesystem->remove($this->getPath($storageOptions));
  100.         } catch (IOException $ex) {
  101.         }
  102.     }
  103.     /**
  104.      * Get a unique filename in path.
  105.      */
  106.     private function getUniqueFileName(string $parentPathstring $fileNameint $counter 0): string
  107.     {
  108.         $newFileName $fileName;
  109.         if ($counter 0) {
  110.             $fileNameParts \explode('.'$fileName2);
  111.             $newFileName $fileNameParts[0] . '-' $counter;
  112.             if (isset($fileNameParts[1])) {
  113.                 $newFileName .= '.' $fileNameParts[1];
  114.             }
  115.         }
  116.         $filePath \rtrim($parentPath'/') . '/' \ltrim($newFileName'/');
  117.         $this->logger->debug('Check FilePath: ' $filePath);
  118.         if (!$this->filesystem->exists($filePath)) {
  119.             return $newFileName;
  120.         }
  121.         ++$counter;
  122.         return $this->getUniqueFileName($parentPath$fileName$counter);
  123.     }
  124.     private function getFilesystemPath(?string $directory, ?string $segment null, ?string $fileName null): string
  125.     {
  126.         return \implode('/'\array_filter([$this->uploadPath$directory$segment$fileName]));
  127.     }
  128.     /**
  129.      * @param array<string, string|null> $storageOptions
  130.      */
  131.     private function getStorageOption(array $storageOptionsstring $key): ?string
  132.     {
  133.         return \array_key_exists($key$storageOptions) ? $storageOptions[$key] : null;
  134.     }
  135.     /**
  136.      * @param array<string, string|null> $storageOptions
  137.      */
  138.     private function createDirectories(array $storageOptions): void
  139.     {
  140.         $directory $this->getStorageOption($storageOptions'directory');
  141.         $segment $this->getStorageOption($storageOptions'segment');
  142.         $segmentPath $this->getFilesystemPath($directory$segment);
  143.         if (!$this->filesystem->exists($segmentPath)) {
  144.             $this->logger->debug('Try Create Folder: ' $segmentPath);
  145.             $this->filesystem->mkdir($segmentPath0777);
  146.         }
  147.     }
  148. }