vendor/league/flysystem/src/Filesystem.php line 150

  1. <?php
  2. declare(strict_types=1);
  3. namespace League\Flysystem;
  4. use DateTimeInterface;
  5. use Generator;
  6. use League\Flysystem\UrlGeneration\ShardedPrefixPublicUrlGenerator;
  7. use League\Flysystem\UrlGeneration\PrefixPublicUrlGenerator;
  8. use League\Flysystem\UrlGeneration\PublicUrlGenerator;
  9. use League\Flysystem\UrlGeneration\TemporaryUrlGenerator;
  10. use Throwable;
  11. use function is_array;
  12. class Filesystem implements FilesystemOperator
  13. {
  14.     use CalculateChecksumFromStream;
  15.     private Config $config;
  16.     private PathNormalizer $pathNormalizer;
  17.     public function __construct(
  18.         private FilesystemAdapter $adapter,
  19.         array $config = [],
  20.         PathNormalizer $pathNormalizer null,
  21.         private ?PublicUrlGenerator $publicUrlGenerator null,
  22.         private ?TemporaryUrlGenerator $temporaryUrlGenerator null,
  23.     ) {
  24.         $this->config = new Config($config);
  25.         $this->pathNormalizer $pathNormalizer ?: new WhitespacePathNormalizer();
  26.     }
  27.     public function fileExists(string $location): bool
  28.     {
  29.         return $this->adapter->fileExists($this->pathNormalizer->normalizePath($location));
  30.     }
  31.     public function directoryExists(string $location): bool
  32.     {
  33.         return $this->adapter->directoryExists($this->pathNormalizer->normalizePath($location));
  34.     }
  35.     public function has(string $location): bool
  36.     {
  37.         $path $this->pathNormalizer->normalizePath($location);
  38.         return $this->adapter->fileExists($path) || $this->adapter->directoryExists($path);
  39.     }
  40.     public function write(string $locationstring $contents, array $config = []): void
  41.     {
  42.         $this->adapter->write(
  43.             $this->pathNormalizer->normalizePath($location),
  44.             $contents,
  45.             $this->config->extend($config)
  46.         );
  47.     }
  48.     public function writeStream(string $location$contents, array $config = []): void
  49.     {
  50.         /* @var resource $contents */
  51.         $this->assertIsResource($contents);
  52.         $this->rewindStream($contents);
  53.         $this->adapter->writeStream(
  54.             $this->pathNormalizer->normalizePath($location),
  55.             $contents,
  56.             $this->config->extend($config)
  57.         );
  58.     }
  59.     public function read(string $location): string
  60.     {
  61.         return $this->adapter->read($this->pathNormalizer->normalizePath($location));
  62.     }
  63.     public function readStream(string $location)
  64.     {
  65.         return $this->adapter->readStream($this->pathNormalizer->normalizePath($location));
  66.     }
  67.     public function delete(string $location): void
  68.     {
  69.         $this->adapter->delete($this->pathNormalizer->normalizePath($location));
  70.     }
  71.     public function deleteDirectory(string $location): void
  72.     {
  73.         $this->adapter->deleteDirectory($this->pathNormalizer->normalizePath($location));
  74.     }
  75.     public function createDirectory(string $location, array $config = []): void
  76.     {
  77.         $this->adapter->createDirectory(
  78.             $this->pathNormalizer->normalizePath($location),
  79.             $this->config->extend($config)
  80.         );
  81.     }
  82.     public function listContents(string $locationbool $deep self::LIST_SHALLOW): DirectoryListing
  83.     {
  84.         $path $this->pathNormalizer->normalizePath($location);
  85.         $listing $this->adapter->listContents($path$deep);
  86.         return new DirectoryListing($this->pipeListing($location$deep$listing));
  87.     }
  88.     private function pipeListing(string $locationbool $deepiterable $listing): Generator
  89.     {
  90.         try {
  91.             foreach ($listing as $item) {
  92.                 yield $item;
  93.             }
  94.         } catch (Throwable $exception) {
  95.             throw UnableToListContents::atLocation($location$deep$exception);
  96.         }
  97.     }
  98.     public function move(string $sourcestring $destination, array $config = []): void
  99.     {
  100.         $this->adapter->move(
  101.             $this->pathNormalizer->normalizePath($source),
  102.             $this->pathNormalizer->normalizePath($destination),
  103.             $this->config->extend($config)
  104.         );
  105.     }
  106.     public function copy(string $sourcestring $destination, array $config = []): void
  107.     {
  108.         $this->adapter->copy(
  109.             $this->pathNormalizer->normalizePath($source),
  110.             $this->pathNormalizer->normalizePath($destination),
  111.             $this->config->extend($config)
  112.         );
  113.     }
  114.     public function lastModified(string $path): int
  115.     {
  116.         return $this->adapter->lastModified($this->pathNormalizer->normalizePath($path))->lastModified();
  117.     }
  118.     public function fileSize(string $path): int
  119.     {
  120.         return $this->adapter->fileSize($this->pathNormalizer->normalizePath($path))->fileSize();
  121.     }
  122.     public function mimeType(string $path): string
  123.     {
  124.         return $this->adapter->mimeType($this->pathNormalizer->normalizePath($path))->mimeType();
  125.     }
  126.     public function setVisibility(string $pathstring $visibility): void
  127.     {
  128.         $this->adapter->setVisibility($this->pathNormalizer->normalizePath($path), $visibility);
  129.     }
  130.     public function visibility(string $path): string
  131.     {
  132.         return $this->adapter->visibility($this->pathNormalizer->normalizePath($path))->visibility();
  133.     }
  134.     public function publicUrl(string $path, array $config = []): string
  135.     {
  136.         $this->publicUrlGenerator ??= $this->resolvePublicUrlGenerator()
  137.             ?: throw UnableToGeneratePublicUrl::noGeneratorConfigured($path);
  138.         $config $this->config->extend($config);
  139.         return $this->publicUrlGenerator->publicUrl($path$config);
  140.     }
  141.     public function temporaryUrl(string $pathDateTimeInterface $expiresAt, array $config = []): string
  142.     {
  143.         $generator $this->temporaryUrlGenerator ?: $this->adapter;
  144.         if ($generator instanceof TemporaryUrlGenerator) {
  145.             return $generator->temporaryUrl($path$expiresAt$this->config->extend($config));
  146.         }
  147.         throw UnableToGenerateTemporaryUrl::noGeneratorConfigured($path);
  148.     }
  149.     public function checksum(string $path, array $config = []): string
  150.     {
  151.         $config $this->config->extend($config);
  152.         if ( ! $this->adapter instanceof ChecksumProvider) {
  153.             return $this->calculateChecksumFromStream($path$config);
  154.         }
  155.         try {
  156.             return $this->adapter->checksum($path$config);
  157.         } catch (ChecksumAlgoIsNotSupported) {
  158.             return $this->calculateChecksumFromStream($path$config);
  159.         }
  160.     }
  161.     private function resolvePublicUrlGenerator(): ?PublicUrlGenerator
  162.     {
  163.         if ($publicUrl $this->config->get('public_url')) {
  164.             return match (true) {
  165.                 is_array($publicUrl) => new ShardedPrefixPublicUrlGenerator($publicUrl),
  166.                 default => new PrefixPublicUrlGenerator($publicUrl),
  167.             };
  168.         }
  169.         if ($this->adapter instanceof PublicUrlGenerator) {
  170.             return $this->adapter;
  171.         }
  172.         return null;
  173.     }
  174.     /**
  175.      * @param mixed $contents
  176.      */
  177.     private function assertIsResource($contents): void
  178.     {
  179.         if (is_resource($contents) === false) {
  180.             throw new InvalidStreamProvided(
  181.                 "Invalid stream provided, expected stream resource, received " gettype($contents)
  182.             );
  183.         } elseif ($type get_resource_type($contents) !== 'stream') {
  184.             throw new InvalidStreamProvided(
  185.                 "Invalid stream provided, expected stream resource, received resource of type " $type
  186.             );
  187.         }
  188.     }
  189.     /**
  190.      * @param resource $resource
  191.      */
  192.     private function rewindStream($resource): void
  193.     {
  194.         if (ftell($resource) !== && stream_get_meta_data($resource)['seekable']) {
  195.             rewind($resource);
  196.         }
  197.     }
  198. }