Updated Symfony/Filesystem from version 6.3.1 to 7.1.2
This commit is contained in:
parent
e624663f62
commit
1bcfe90bea
6 changed files with 76 additions and 65 deletions
|
@ -1,6 +1,16 @@
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
7.1
|
||||||
|
---
|
||||||
|
|
||||||
|
* Add the `Filesystem::readFile()` method
|
||||||
|
|
||||||
|
7.0
|
||||||
|
---
|
||||||
|
|
||||||
|
* Add argument `$lock` to `Filesystem::appendToFile()`
|
||||||
|
|
||||||
5.4
|
5.4
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace ncc\ThirdParty\Symfony\Filesystem\Exception;
|
||||||
*/
|
*/
|
||||||
class FileNotFoundException extends IOException
|
class FileNotFoundException extends IOException
|
||||||
{
|
{
|
||||||
public function __construct(string $message = null, int $code = 0, \Throwable $previous = null, string $path = null)
|
public function __construct(?string $message = null, int $code = 0, ?\Throwable $previous = null, ?string $path = null)
|
||||||
{
|
{
|
||||||
if (null === $message) {
|
if (null === $message) {
|
||||||
if (null === $path) {
|
if (null === $path) {
|
||||||
|
|
|
@ -20,12 +20,12 @@ namespace ncc\ThirdParty\Symfony\Filesystem\Exception;
|
||||||
*/
|
*/
|
||||||
class IOException extends \RuntimeException implements IOExceptionInterface
|
class IOException extends \RuntimeException implements IOExceptionInterface
|
||||||
{
|
{
|
||||||
private ?string $path;
|
public function __construct(
|
||||||
|
string $message,
|
||||||
public function __construct(string $message, int $code = 0, \Throwable $previous = null, string $path = null)
|
int $code = 0,
|
||||||
{
|
?\Throwable $previous = null,
|
||||||
$this->path = $path;
|
private ?string $path = null,
|
||||||
|
) {
|
||||||
parent::__construct($message, $code, $previous);
|
parent::__construct($message, $code, $previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ use ncc\ThirdParty\Symfony\Filesystem\Exception\IOException;
|
||||||
*/
|
*/
|
||||||
class Filesystem
|
class Filesystem
|
||||||
{
|
{
|
||||||
private static $lastError;
|
private static ?string $lastError = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies a file.
|
* Copies a file.
|
||||||
|
@ -31,12 +31,10 @@ class Filesystem
|
||||||
* If the target file is newer, it is overwritten only when the
|
* If the target file is newer, it is overwritten only when the
|
||||||
* $overwriteNewerFiles option is set to true.
|
* $overwriteNewerFiles option is set to true.
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws FileNotFoundException When originFile doesn't exist
|
* @throws FileNotFoundException When originFile doesn't exist
|
||||||
* @throws IOException When copy fails
|
* @throws IOException When copy fails
|
||||||
*/
|
*/
|
||||||
public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false)
|
public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = false): void
|
||||||
{
|
{
|
||||||
$originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://');
|
$originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://');
|
||||||
if ($originIsLocal && !is_file($originFile)) {
|
if ($originIsLocal && !is_file($originFile)) {
|
||||||
|
@ -74,6 +72,9 @@ class Filesystem
|
||||||
// Like `cp`, preserve executable permission bits
|
// Like `cp`, preserve executable permission bits
|
||||||
self::box('chmod', $targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111));
|
self::box('chmod', $targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111));
|
||||||
|
|
||||||
|
// Like `cp`, preserve the file modification time
|
||||||
|
self::box('touch', $targetFile, filemtime($originFile));
|
||||||
|
|
||||||
if ($bytesCopied !== $bytesOrigin = filesize($originFile)) {
|
if ($bytesCopied !== $bytesOrigin = filesize($originFile)) {
|
||||||
throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile);
|
throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile);
|
||||||
}
|
}
|
||||||
|
@ -84,11 +85,9 @@ class Filesystem
|
||||||
/**
|
/**
|
||||||
* Creates a directory recursively.
|
* Creates a directory recursively.
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException On any directory creation failure
|
* @throws IOException On any directory creation failure
|
||||||
*/
|
*/
|
||||||
public function mkdir(string|iterable $dirs, int $mode = 0777)
|
public function mkdir(string|iterable $dirs, int $mode = 0777): void
|
||||||
{
|
{
|
||||||
foreach ($this->toIterable($dirs) as $dir) {
|
foreach ($this->toIterable($dirs) as $dir) {
|
||||||
if (is_dir($dir)) {
|
if (is_dir($dir)) {
|
||||||
|
@ -127,11 +126,9 @@ class Filesystem
|
||||||
* @param int|null $time The touch time as a Unix timestamp, if not supplied the current system time is used
|
* @param int|null $time The touch time as a Unix timestamp, if not supplied the current system time is used
|
||||||
* @param int|null $atime The access time as a Unix timestamp, if not supplied the current system time is used
|
* @param int|null $atime The access time as a Unix timestamp, if not supplied the current system time is used
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException When touch fails
|
* @throws IOException When touch fails
|
||||||
*/
|
*/
|
||||||
public function touch(string|iterable $files, int $time = null, int $atime = null)
|
public function touch(string|iterable $files, ?int $time = null, ?int $atime = null): void
|
||||||
{
|
{
|
||||||
foreach ($this->toIterable($files) as $file) {
|
foreach ($this->toIterable($files) as $file) {
|
||||||
if (!($time ? self::box('touch', $file, $time, $atime) : self::box('touch', $file))) {
|
if (!($time ? self::box('touch', $file, $time, $atime) : self::box('touch', $file))) {
|
||||||
|
@ -143,11 +140,9 @@ class Filesystem
|
||||||
/**
|
/**
|
||||||
* Removes files or directories.
|
* Removes files or directories.
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException When removal fails
|
* @throws IOException When removal fails
|
||||||
*/
|
*/
|
||||||
public function remove(string|iterable $files)
|
public function remove(string|iterable $files): void
|
||||||
{
|
{
|
||||||
if ($files instanceof \Traversable) {
|
if ($files instanceof \Traversable) {
|
||||||
$files = iterator_to_array($files, false);
|
$files = iterator_to_array($files, false);
|
||||||
|
@ -169,7 +164,7 @@ class Filesystem
|
||||||
}
|
}
|
||||||
} elseif (is_dir($file)) {
|
} elseif (is_dir($file)) {
|
||||||
if (!$isRecursive) {
|
if (!$isRecursive) {
|
||||||
$tmpName = \dirname(realpath($file)).'/.'.strrev(strtr(base64_encode(random_bytes(2)), '/=', '-_'));
|
$tmpName = \dirname(realpath($file)).'/.!'.strrev(strtr(base64_encode(random_bytes(2)), '/=', '-!'));
|
||||||
|
|
||||||
if (file_exists($tmpName)) {
|
if (file_exists($tmpName)) {
|
||||||
try {
|
try {
|
||||||
|
@ -198,7 +193,7 @@ class Filesystem
|
||||||
|
|
||||||
throw new IOException(sprintf('Failed to remove directory "%s": ', $file).$lastError);
|
throw new IOException(sprintf('Failed to remove directory "%s": ', $file).$lastError);
|
||||||
}
|
}
|
||||||
} elseif (!self::box('unlink', $file) && (str_contains(self::$lastError, 'Permission denied') || file_exists($file))) {
|
} elseif (!self::box('unlink', $file) && ((self::$lastError && str_contains(self::$lastError, 'Permission denied')) || file_exists($file))) {
|
||||||
throw new IOException(sprintf('Failed to remove file "%s": ', $file).self::$lastError);
|
throw new IOException(sprintf('Failed to remove file "%s": ', $file).self::$lastError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,11 +206,9 @@ class Filesystem
|
||||||
* @param int $umask The mode mask (octal)
|
* @param int $umask The mode mask (octal)
|
||||||
* @param bool $recursive Whether change the mod recursively or not
|
* @param bool $recursive Whether change the mod recursively or not
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException When the change fails
|
* @throws IOException When the change fails
|
||||||
*/
|
*/
|
||||||
public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool $recursive = false)
|
public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool $recursive = false): void
|
||||||
{
|
{
|
||||||
foreach ($this->toIterable($files) as $file) {
|
foreach ($this->toIterable($files) as $file) {
|
||||||
if (!self::box('chmod', $file, $mode & ~$umask)) {
|
if (!self::box('chmod', $file, $mode & ~$umask)) {
|
||||||
|
@ -230,14 +223,15 @@ class Filesystem
|
||||||
/**
|
/**
|
||||||
* Change the owner of an array of files or directories.
|
* Change the owner of an array of files or directories.
|
||||||
*
|
*
|
||||||
|
* This method always throws on Windows, as the underlying PHP function is not supported.
|
||||||
|
* @see https://www.php.net/chown
|
||||||
|
*
|
||||||
* @param string|int $user A user name or number
|
* @param string|int $user A user name or number
|
||||||
* @param bool $recursive Whether change the owner recursively or not
|
* @param bool $recursive Whether change the owner recursively or not
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException When the change fails
|
* @throws IOException When the change fails
|
||||||
*/
|
*/
|
||||||
public function chown(string|iterable $files, string|int $user, bool $recursive = false)
|
public function chown(string|iterable $files, string|int $user, bool $recursive = false): void
|
||||||
{
|
{
|
||||||
foreach ($this->toIterable($files) as $file) {
|
foreach ($this->toIterable($files) as $file) {
|
||||||
if ($recursive && is_dir($file) && !is_link($file)) {
|
if ($recursive && is_dir($file) && !is_link($file)) {
|
||||||
|
@ -258,14 +252,15 @@ class Filesystem
|
||||||
/**
|
/**
|
||||||
* Change the group of an array of files or directories.
|
* Change the group of an array of files or directories.
|
||||||
*
|
*
|
||||||
|
* This method always throws on Windows, as the underlying PHP function is not supported.
|
||||||
|
* @see https://www.php.net/chgrp
|
||||||
|
*
|
||||||
* @param string|int $group A group name or number
|
* @param string|int $group A group name or number
|
||||||
* @param bool $recursive Whether change the group recursively or not
|
* @param bool $recursive Whether change the group recursively or not
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException When the change fails
|
* @throws IOException When the change fails
|
||||||
*/
|
*/
|
||||||
public function chgrp(string|iterable $files, string|int $group, bool $recursive = false)
|
public function chgrp(string|iterable $files, string|int $group, bool $recursive = false): void
|
||||||
{
|
{
|
||||||
foreach ($this->toIterable($files) as $file) {
|
foreach ($this->toIterable($files) as $file) {
|
||||||
if ($recursive && is_dir($file) && !is_link($file)) {
|
if ($recursive && is_dir($file) && !is_link($file)) {
|
||||||
|
@ -286,12 +281,10 @@ class Filesystem
|
||||||
/**
|
/**
|
||||||
* Renames a file or a directory.
|
* Renames a file or a directory.
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException When target file or directory already exists
|
* @throws IOException When target file or directory already exists
|
||||||
* @throws IOException When origin cannot be renamed
|
* @throws IOException When origin cannot be renamed
|
||||||
*/
|
*/
|
||||||
public function rename(string $origin, string $target, bool $overwrite = false)
|
public function rename(string $origin, string $target, bool $overwrite = false): void
|
||||||
{
|
{
|
||||||
// we check that target does not exist
|
// we check that target does not exist
|
||||||
if (!$overwrite && $this->isReadable($target)) {
|
if (!$overwrite && $this->isReadable($target)) {
|
||||||
|
@ -329,11 +322,9 @@ class Filesystem
|
||||||
/**
|
/**
|
||||||
* Creates a symbolic link or copy a directory.
|
* Creates a symbolic link or copy a directory.
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException When symlink fails
|
* @throws IOException When symlink fails
|
||||||
*/
|
*/
|
||||||
public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false)
|
public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false): void
|
||||||
{
|
{
|
||||||
self::assertFunctionExists('symlink');
|
self::assertFunctionExists('symlink');
|
||||||
|
|
||||||
|
@ -367,12 +358,10 @@ class Filesystem
|
||||||
*
|
*
|
||||||
* @param string|string[] $targetFiles The target file(s)
|
* @param string|string[] $targetFiles The target file(s)
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws FileNotFoundException When original file is missing or not a file
|
* @throws FileNotFoundException When original file is missing or not a file
|
||||||
* @throws IOException When link fails, including if link already exists
|
* @throws IOException When link fails, including if link already exists
|
||||||
*/
|
*/
|
||||||
public function hardlink(string $originFile, string|iterable $targetFiles)
|
public function hardlink(string $originFile, string|iterable $targetFiles): void
|
||||||
{
|
{
|
||||||
self::assertFunctionExists('link');
|
self::assertFunctionExists('link');
|
||||||
|
|
||||||
|
@ -526,11 +515,9 @@ class Filesystem
|
||||||
* - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false)
|
* - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false)
|
||||||
* - $options['delete'] Whether to delete files that are not in the source directory (defaults to false)
|
* - $options['delete'] Whether to delete files that are not in the source directory (defaults to false)
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException When file type is unknown
|
* @throws IOException When file type is unknown
|
||||||
*/
|
*/
|
||||||
public function mirror(string $originDir, string $targetDir, \Traversable $iterator = null, array $options = [])
|
public function mirror(string $originDir, string $targetDir, ?\Traversable $iterator = null, array $options = []): void
|
||||||
{
|
{
|
||||||
$targetDir = rtrim($targetDir, '/\\');
|
$targetDir = rtrim($targetDir, '/\\');
|
||||||
$originDir = rtrim($originDir, '/\\');
|
$originDir = rtrim($originDir, '/\\');
|
||||||
|
@ -652,11 +639,9 @@ class Filesystem
|
||||||
*
|
*
|
||||||
* @param string|resource $content The data to write into the file
|
* @param string|resource $content The data to write into the file
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException if the file cannot be written to
|
* @throws IOException if the file cannot be written to
|
||||||
*/
|
*/
|
||||||
public function dumpFile(string $filename, $content)
|
public function dumpFile(string $filename, $content): void
|
||||||
{
|
{
|
||||||
if (\is_array($content)) {
|
if (\is_array($content)) {
|
||||||
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
|
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
|
||||||
|
@ -683,11 +668,15 @@ class Filesystem
|
||||||
throw new IOException(sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename);
|
throw new IOException(sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
self::box('chmod', $tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask());
|
self::box('chmod', $tmpFile, self::box('fileperms', $filename) ?: 0666 & ~umask());
|
||||||
|
|
||||||
$this->rename($tmpFile, $filename, true);
|
$this->rename($tmpFile, $filename, true);
|
||||||
} finally {
|
} finally {
|
||||||
if (file_exists($tmpFile)) {
|
if (file_exists($tmpFile)) {
|
||||||
|
if ('\\' === \DIRECTORY_SEPARATOR && !is_writable($tmpFile)) {
|
||||||
|
self::box('chmod', $tmpFile, self::box('fileperms', $tmpFile) | 0200);
|
||||||
|
}
|
||||||
|
|
||||||
self::box('unlink', $tmpFile);
|
self::box('unlink', $tmpFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -699,11 +688,9 @@ class Filesystem
|
||||||
* @param string|resource $content The content to append
|
* @param string|resource $content The content to append
|
||||||
* @param bool $lock Whether the file should be locked when writing to it
|
* @param bool $lock Whether the file should be locked when writing to it
|
||||||
*
|
*
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @throws IOException If the file is not writable
|
* @throws IOException If the file is not writable
|
||||||
*/
|
*/
|
||||||
public function appendToFile(string $filename, $content/* , bool $lock = false */)
|
public function appendToFile(string $filename, $content, bool $lock = false): void
|
||||||
{
|
{
|
||||||
if (\is_array($content)) {
|
if (\is_array($content)) {
|
||||||
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
|
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
|
||||||
|
@ -715,13 +702,30 @@ class Filesystem
|
||||||
$this->mkdir($dir);
|
$this->mkdir($dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
$lock = \func_num_args() > 2 && func_get_arg(2);
|
|
||||||
|
|
||||||
if (false === self::box('file_put_contents', $filename, $content, \FILE_APPEND | ($lock ? \LOCK_EX : 0))) {
|
if (false === self::box('file_put_contents', $filename, $content, \FILE_APPEND | ($lock ? \LOCK_EX : 0))) {
|
||||||
throw new IOException(sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename);
|
throw new IOException(sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the content of a file as a string.
|
||||||
|
*
|
||||||
|
* @throws IOException If the file cannot be read
|
||||||
|
*/
|
||||||
|
public function readFile(string $filename): string
|
||||||
|
{
|
||||||
|
if (is_dir($filename)) {
|
||||||
|
throw new IOException(sprintf('Failed to read file "%s": File is a directory.', $filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = self::box('file_get_contents', $filename);
|
||||||
|
if (false === $content) {
|
||||||
|
throw new IOException(sprintf('Failed to read file "%s": ', $filename).self::$lastError, 0, null, $filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
private function toIterable(string|iterable $files): iterable
|
private function toIterable(string|iterable $files): iterable
|
||||||
{
|
{
|
||||||
return is_iterable($files) ? $files : [$files];
|
return is_iterable($files) ? $files : [$files];
|
||||||
|
@ -749,7 +753,7 @@ class Filesystem
|
||||||
self::assertFunctionExists($func);
|
self::assertFunctionExists($func);
|
||||||
|
|
||||||
self::$lastError = null;
|
self::$lastError = null;
|
||||||
set_error_handler(__CLASS__.'::handleError');
|
set_error_handler(self::handleError(...));
|
||||||
try {
|
try {
|
||||||
return $func(...$args);
|
return $func(...$args);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
19
src/ncc/ThirdParty/Symfony/Filesystem/Path.php
vendored
19
src/ncc/ThirdParty/Symfony/Filesystem/Path.php
vendored
|
@ -42,12 +42,9 @@ final class Path
|
||||||
*
|
*
|
||||||
* @var array<string, string>
|
* @var array<string, string>
|
||||||
*/
|
*/
|
||||||
private static $buffer = [];
|
private static array $buffer = [];
|
||||||
|
|
||||||
/**
|
private static int $bufferSize = 0;
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private static $bufferSize = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Canonicalizes the given path.
|
* Canonicalizes the given path.
|
||||||
|
@ -257,7 +254,7 @@ final class Path
|
||||||
* @param string|null $extension if specified, only that extension is cut
|
* @param string|null $extension if specified, only that extension is cut
|
||||||
* off (may contain leading dot)
|
* off (may contain leading dot)
|
||||||
*/
|
*/
|
||||||
public static function getFilenameWithoutExtension(string $path, string $extension = null): string
|
public static function getFilenameWithoutExtension(string $path, ?string $extension = null): string
|
||||||
{
|
{
|
||||||
if ('' === $path) {
|
if ('' === $path) {
|
||||||
return '';
|
return '';
|
||||||
|
@ -349,13 +346,13 @@ final class Path
|
||||||
$extension = ltrim($extension, '.');
|
$extension = ltrim($extension, '.');
|
||||||
|
|
||||||
// No extension for paths
|
// No extension for paths
|
||||||
if ('/' === substr($path, -1)) {
|
if (str_ends_with($path, '/')) {
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No actual extension in path
|
// No actual extension in path
|
||||||
if (empty($actualExtension)) {
|
if (!$actualExtension) {
|
||||||
return $path.('.' === substr($path, -1) ? '' : '.').$extension;
|
return $path.(str_ends_with($path, '.') ? '' : '.').$extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
return substr($path, 0, -\strlen($actualExtension)).$extension;
|
return substr($path, 0, -\strlen($actualExtension)).$extension;
|
||||||
|
@ -368,7 +365,7 @@ final class Path
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strip scheme
|
// Strip scheme
|
||||||
if (false !== $schemeSeparatorPosition = strpos($path, '://')) {
|
if (false !== ($schemeSeparatorPosition = strpos($path, '://')) && 1 !== $schemeSeparatorPosition) {
|
||||||
$path = substr($path, $schemeSeparatorPosition + 3);
|
$path = substr($path, $schemeSeparatorPosition + 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,7 +668,7 @@ final class Path
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only add slash if previous part didn't end with '/' or '\'
|
// Only add slash if previous part didn't end with '/' or '\'
|
||||||
if (!\in_array(substr($finalPath, -1), ['/', '\\'])) {
|
if (!\in_array(substr($finalPath, -1), ['/', '\\'], true)) {
|
||||||
$finalPath .= '/';
|
$finalPath .= '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
6.3.1
|
7.1.2
|
Loading…
Add table
Reference in a new issue