/
home
/
sjslayjy
/
public_html
/
theweavenest
/
vendor
/
league
/
flysystem
/
src
/
PhpseclibV3
/
Upload File
HOME
<?php declare(strict_types=1); namespace League\Flysystem\PhpseclibV3; use League\Flysystem\Config; use League\Flysystem\DirectoryAttributes; use League\Flysystem\FileAttributes; use League\Flysystem\FilesystemAdapter; use League\Flysystem\FilesystemException; use League\Flysystem\PathPrefixer; use League\Flysystem\StorageAttributes; use League\Flysystem\UnableToCheckDirectoryExistence; use League\Flysystem\UnableToCheckFileExistence; use League\Flysystem\UnableToCopyFile; use League\Flysystem\UnableToCreateDirectory; use League\Flysystem\UnableToMoveFile; use League\Flysystem\UnableToReadFile; use League\Flysystem\UnableToRetrieveMetadata; use League\Flysystem\UnableToSetVisibility; use League\Flysystem\UnableToWriteFile; use League\Flysystem\UnixVisibility\PortableVisibilityConverter; use League\Flysystem\UnixVisibility\VisibilityConverter; use League\MimeTypeDetection\FinfoMimeTypeDetector; use League\MimeTypeDetection\MimeTypeDetector; use phpseclib3\Net\SFTP; use Throwable; use function rtrim; class SftpAdapter implements FilesystemAdapter { private VisibilityConverter $visibilityConverter; private PathPrefixer $prefixer; private MimeTypeDetector $mimeTypeDetector; public function __construct( private ConnectionProvider $connectionProvider, string $root, ?VisibilityConverter $visibilityConverter = null, ?MimeTypeDetector $mimeTypeDetector = null, private bool $detectMimeTypeUsingPath = false, ) { $this->prefixer = new PathPrefixer($root); $this->visibilityConverter = $visibilityConverter ?? new PortableVisibilityConverter(); $this->mimeTypeDetector = $mimeTypeDetector ?? new FinfoMimeTypeDetector(); } public function fileExists(string $path): bool { $location = $this->prefixer->prefixPath($path); try { return $this->connectionProvider->provideConnection()->is_file($location); } catch (Throwable $exception) { throw UnableToCheckFileExistence::forLocation($path, $exception); } } public function disconnect(): void { $this->connectionProvider->disconnect(); } public function directoryExists(string $path): bool { $location = $this->prefixer->prefixDirectoryPath($path); try { return $this->connectionProvider->provideConnection()->is_dir($location); } catch (Throwable $exception) { throw UnableToCheckDirectoryExistence::forLocation($path, $exception); } } /** * @param string $path * @param string|resource $contents * @param Config $config * * @throws FilesystemException */ private function upload(string $path, $contents, Config $config): void { $this->ensureParentDirectoryExists($path, $config); $connection = $this->connectionProvider->provideConnection(); $location = $this->prefixer->prefixPath($path); if ( ! $connection->put($location, $contents, SFTP::SOURCE_STRING)) { throw UnableToWriteFile::atLocation($path, 'not able to write the file'); } if ($visibility = $config->get(Config::OPTION_VISIBILITY)) { $this->setVisibility($path, $visibility); } } private function ensureParentDirectoryExists(string $path, Config $config): void { $parentDirectory = dirname($path); if ($parentDirectory === '' || $parentDirectory === '.') { return; } /** @var string $visibility */ $visibility = $config->get(Config::OPTION_DIRECTORY_VISIBILITY); $this->makeDirectory($parentDirectory, $visibility); } private function makeDirectory(string $directory, ?string $visibility): void { $location = $this->prefixer->prefixPath($directory); $connection = $this->connectionProvider->provideConnection(); if ($connection->is_dir($location)) { return; } $mode = $visibility ? $this->visibilityConverter->forDirectory( $visibility ) : $this->visibilityConverter->defaultForDirectories(); if ( ! $connection->mkdir($location, $mode, true) && ! $connection->is_dir($location)) { throw UnableToCreateDirectory::atLocation($directory); } } public function write(string $path, string $contents, Config $config): void { try { $this->upload($path, $contents, $config); } catch (UnableToWriteFile $exception) { throw $exception; } catch (Throwable $exception) { throw UnableToWriteFile::atLocation($path, $exception->getMessage(), $exception); } } public function writeStream(string $path, $contents, Config $config): void { try { $this->upload($path, $contents, $config); } catch (UnableToWriteFile $exception) { throw $exception; } catch (Throwable $exception) { throw UnableToWriteFile::atLocation($path, $exception->getMessage(), $exception); } } public function read(string $path): string { $location = $this->prefixer->prefixPath($path); $connection = $this->connectionProvider->provideConnection(); $contents = $connection->get($location); if ( ! is_string($contents)) { throw UnableToReadFile::fromLocation($path); } return $contents; } public function readStream(string $path) { $location = $this->prefixer->prefixPath($path); $connection = $this->connectionProvider->provideConnection(); /** @var resource $readStream */ $readStream = fopen('php://temp', 'w+'); if ( ! $connection->get($location, $readStream)) { fclose($readStream); throw UnableToReadFile::fromLocation($path); } rewind($readStream); return $readStream; } public function delete(string $path): void { $location = $this->prefixer->prefixPath($path); $connection = $this->connectionProvider->provideConnection(); $connection->delete($location); } public function deleteDirectory(string $path): void { $location = rtrim($this->prefixer->prefixPath($path), '/') . '/'; $connection = $this->connectionProvider->provideConnection(); $connection->delete($location); $connection->rmdir($location); } public function createDirectory(string $path, Config $config): void { $this->makeDirectory($path, $config->get(Config::OPTION_DIRECTORY_VISIBILITY, $config->get(Config::OPTION_VISIBILITY))); } public function setVisibility(string $path, string $visibility): void { $location = $this->prefixer->prefixPath($path); $connection = $this->connectionProvider->provideConnection(); $mode = $this->visibilityConverter->forFile($visibility); if ( ! $connection->chmod($mode, $location, false)) { throw UnableToSetVisibility::atLocation($path); } } private function fetchFileMetadata(string $path, string $type): FileAttributes { $location = $this->prefixer->prefixPath($path); $connection = $this->connectionProvider->provideConnection(); $stat = $connection->stat($location); if ( ! is_array($stat)) { throw UnableToRetrieveMetadata::create($path, $type); } $attributes = $this->convertListingToAttributes($path, $stat); if ( ! $attributes instanceof FileAttributes) { throw UnableToRetrieveMetadata::create($path, $type, 'path is not a file'); } return $attributes; } public function mimeType(string $path): FileAttributes { try { $mimetype = $this->detectMimeTypeUsingPath ? $this->mimeTypeDetector->detectMimeTypeFromPath($path) : $this->mimeTypeDetector->detectMimeType($path, $this->read($path)); } catch (Throwable $exception) { throw UnableToRetrieveMetadata::mimeType($path, $exception->getMessage(), $exception); } if ($mimetype === null) { throw UnableToRetrieveMetadata::mimeType($path, 'Unknown.'); } return new FileAttributes($path, null, null, null, $mimetype); } public function lastModified(string $path): FileAttributes { return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_LAST_MODIFIED); } public function fileSize(string $path): FileAttributes { return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_FILE_SIZE); } public function visibility(string $path): FileAttributes { return $this->fetchFileMetadata($path, FileAttributes::ATTRIBUTE_VISIBILITY); } public function listContents(string $path, bool $deep): iterable { $connection = $this->connectionProvider->provideConnection(); $location = $this->prefixer->prefixPath(rtrim($path, '/')) . '/'; $listing = $connection->rawlist($location, false); if (false === $listing) { return; } foreach ($listing as $filename => $attributes) { if ($filename === '.' || $filename === '..') { continue; } // Ensure numeric keys are strings. $filename = (string) $filename; $path = $this->prefixer->stripPrefix($location . ltrim($filename, '/')); $attributes = $this->convertListingToAttributes($path, $attributes); yield $attributes; if ($deep && $attributes->isDir()) { foreach ($this->listContents($attributes->path(), true) as $child) { yield $child; } } } } private function convertListingToAttributes(string $path, array $attributes): StorageAttributes { $permissions = $attributes['mode'] & 0777; $lastModified = $attributes['mtime'] ?? null; if (($attributes['type'] ?? null) === NET_SFTP_TYPE_DIRECTORY) { return new DirectoryAttributes( ltrim($path, '/'), $this->visibilityConverter->inverseForDirectory($permissions), $lastModified ); } return new FileAttributes( $path, $attributes['size'], $this->visibilityConverter->inverseForFile($permissions), $lastModified ); } public function move(string $source, string $destination, Config $config): void { $sourceLocation = $this->prefixer->prefixPath($source); $destinationLocation = $this->prefixer->prefixPath($destination); $connection = $this->connectionProvider->provideConnection(); try { $this->ensureParentDirectoryExists($destination, $config); } catch (Throwable $exception) { throw UnableToMoveFile::fromLocationTo($source, $destination, $exception); } if ($sourceLocation === $destinationLocation) { return; } if ($connection->rename($sourceLocation, $destinationLocation)) { return; } // Overwrite existing file / dir if ($connection->is_file($destinationLocation)) { $this->delete($destination); if ($connection->rename($sourceLocation, $destinationLocation)) { return; } } throw UnableToMoveFile::fromLocationTo($source, $destination); } public function copy(string $source, string $destination, Config $config): void { try { $readStream = $this->readStream($source); $visibility = $config->get(Config::OPTION_VISIBILITY); if ($visibility === null && $config->get(Config::OPTION_RETAIN_VISIBILITY, true)) { $config = $config->withSetting(Config::OPTION_VISIBILITY, $this->visibility($source)->visibility()); } $this->writeStream($destination, $readStream, $config); } catch (Throwable $exception) { if (isset($readStream) && is_resource($readStream)) { @fclose($readStream); } throw UnableToCopyFile::fromLocationTo($source, $destination, $exception); } } }