mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-02 06:58:49 +02:00
N°8834 - Add compatibility with PHP 8.4 (#819)
* N°8834 - Add compatibility with PHP 8.4 * Rollback of scssphp/scssphp version upgrade due to compilation error
This commit is contained in:
@@ -40,25 +40,25 @@ class Filesystem
|
||||
{
|
||||
$originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://');
|
||||
if ($originIsLocal && !is_file($originFile)) {
|
||||
throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile);
|
||||
throw new FileNotFoundException(\sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile);
|
||||
}
|
||||
|
||||
$this->mkdir(\dirname($targetFile));
|
||||
|
||||
$doCopy = true;
|
||||
if (!$overwriteNewerFiles && null === parse_url($originFile, \PHP_URL_HOST) && is_file($targetFile)) {
|
||||
if (!$overwriteNewerFiles && !parse_url($originFile, \PHP_URL_HOST) && is_file($targetFile)) {
|
||||
$doCopy = filemtime($originFile) > filemtime($targetFile);
|
||||
}
|
||||
|
||||
if ($doCopy) {
|
||||
// https://bugs.php.net/64634
|
||||
if (!$source = self::box('fopen', $originFile, 'r')) {
|
||||
throw new IOException(sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading: ', $originFile, $targetFile).self::$lastError, 0, null, $originFile);
|
||||
throw new IOException(\sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading: ', $originFile, $targetFile).self::$lastError, 0, null, $originFile);
|
||||
}
|
||||
|
||||
// Stream context created to allow files overwrite when using FTP stream wrapper - disabled by default
|
||||
if (!$target = self::box('fopen', $targetFile, 'w', false, stream_context_create(['ftp' => ['overwrite' => true]]))) {
|
||||
throw new IOException(sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing: ', $originFile, $targetFile).self::$lastError, 0, null, $originFile);
|
||||
throw new IOException(\sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing: ', $originFile, $targetFile).self::$lastError, 0, null, $originFile);
|
||||
}
|
||||
|
||||
$bytesCopied = stream_copy_to_stream($source, $target);
|
||||
@@ -67,15 +67,18 @@ class Filesystem
|
||||
unset($source, $target);
|
||||
|
||||
if (!is_file($targetFile)) {
|
||||
throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile);
|
||||
throw new IOException(\sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile);
|
||||
}
|
||||
|
||||
if ($originIsLocal) {
|
||||
// Like `cp`, preserve executable permission bits
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,7 +99,7 @@ class Filesystem
|
||||
}
|
||||
|
||||
if (!self::box('mkdir', $dir, $mode, true) && !is_dir($dir)) {
|
||||
throw new IOException(sprintf('Failed to create "%s": ', $dir).self::$lastError, 0, null, $dir);
|
||||
throw new IOException(\sprintf('Failed to create "%s": ', $dir).self::$lastError, 0, null, $dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +113,7 @@ class Filesystem
|
||||
|
||||
foreach ($this->toIterable($files) as $file) {
|
||||
if (\strlen($file) > $maxPathLength) {
|
||||
throw new IOException(sprintf('Could not check if file exist because path length exceeds %d characters.', $maxPathLength), 0, null, $file);
|
||||
throw new IOException(\sprintf('Could not check if file exist because path length exceeds %d characters.', $maxPathLength), 0, null, $file);
|
||||
}
|
||||
|
||||
if (!file_exists($file)) {
|
||||
@@ -131,11 +134,11 @@ class Filesystem
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
foreach ($this->toIterable($files) as $file) {
|
||||
if (!($time ? self::box('touch', $file, $time, $atime) : self::box('touch', $file))) {
|
||||
throw new IOException(sprintf('Failed to touch "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
throw new IOException(\sprintf('Failed to touch "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -165,11 +168,11 @@ class Filesystem
|
||||
if (is_link($file)) {
|
||||
// See https://bugs.php.net/52176
|
||||
if (!(self::box('unlink', $file) || '\\' !== \DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) {
|
||||
throw new IOException(sprintf('Failed to remove symlink "%s": ', $file).self::$lastError);
|
||||
throw new IOException(\sprintf('Failed to remove symlink "%s": ', $file).self::$lastError);
|
||||
}
|
||||
} elseif (is_dir($file)) {
|
||||
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)) {
|
||||
try {
|
||||
@@ -196,10 +199,10 @@ class Filesystem
|
||||
$file = $origFile;
|
||||
}
|
||||
|
||||
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))) {
|
||||
throw new IOException(sprintf('Failed to remove file "%s": ', $file).self::$lastError);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,7 +222,7 @@ class Filesystem
|
||||
{
|
||||
foreach ($this->toIterable($files) as $file) {
|
||||
if (!self::box('chmod', $file, $mode & ~$umask)) {
|
||||
throw new IOException(sprintf('Failed to chmod file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
throw new IOException(\sprintf('Failed to chmod file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
}
|
||||
if ($recursive && is_dir($file) && !is_link($file)) {
|
||||
$this->chmod(new \FilesystemIterator($file), $mode, $umask, true);
|
||||
@@ -230,6 +233,10 @@ class Filesystem
|
||||
/**
|
||||
* 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://php.net/chown
|
||||
*
|
||||
* @param string|int $user A user name or number
|
||||
* @param bool $recursive Whether change the owner recursively or not
|
||||
*
|
||||
@@ -245,11 +252,11 @@ class Filesystem
|
||||
}
|
||||
if (is_link($file) && \function_exists('lchown')) {
|
||||
if (!self::box('lchown', $file, $user)) {
|
||||
throw new IOException(sprintf('Failed to chown file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
throw new IOException(\sprintf('Failed to chown file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
}
|
||||
} else {
|
||||
if (!self::box('chown', $file, $user)) {
|
||||
throw new IOException(sprintf('Failed to chown file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
throw new IOException(\sprintf('Failed to chown file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,6 +265,10 @@ class Filesystem
|
||||
/**
|
||||
* 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://php.net/chgrp
|
||||
*
|
||||
* @param string|int $group A group name or number
|
||||
* @param bool $recursive Whether change the group recursively or not
|
||||
*
|
||||
@@ -273,11 +284,11 @@ class Filesystem
|
||||
}
|
||||
if (is_link($file) && \function_exists('lchgrp')) {
|
||||
if (!self::box('lchgrp', $file, $group)) {
|
||||
throw new IOException(sprintf('Failed to chgrp file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
throw new IOException(\sprintf('Failed to chgrp file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
}
|
||||
} else {
|
||||
if (!self::box('chgrp', $file, $group)) {
|
||||
throw new IOException(sprintf('Failed to chgrp file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
throw new IOException(\sprintf('Failed to chgrp file "%s": ', $file).self::$lastError, 0, null, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,7 +306,7 @@ class Filesystem
|
||||
{
|
||||
// we check that target does not exist
|
||||
if (!$overwrite && $this->isReadable($target)) {
|
||||
throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target);
|
||||
throw new IOException(\sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target);
|
||||
}
|
||||
|
||||
if (!self::box('rename', $origin, $target)) {
|
||||
@@ -306,7 +317,7 @@ class Filesystem
|
||||
|
||||
return;
|
||||
}
|
||||
throw new IOException(sprintf('Cannot rename "%s" to "%s": ', $origin, $target).self::$lastError, 0, null, $target);
|
||||
throw new IOException(\sprintf('Cannot rename "%s" to "%s": ', $origin, $target).self::$lastError, 0, null, $target);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,7 +331,7 @@ class Filesystem
|
||||
$maxPathLength = \PHP_MAXPATHLEN - 2;
|
||||
|
||||
if (\strlen($filename) > $maxPathLength) {
|
||||
throw new IOException(sprintf('Could not check if file is readable because path length exceeds %d characters.', $maxPathLength), 0, null, $filename);
|
||||
throw new IOException(\sprintf('Could not check if file is readable because path length exceeds %d characters.', $maxPathLength), 0, null, $filename);
|
||||
}
|
||||
|
||||
return is_readable($filename);
|
||||
@@ -381,7 +392,7 @@ class Filesystem
|
||||
}
|
||||
|
||||
if (!is_file($originFile)) {
|
||||
throw new FileNotFoundException(sprintf('Origin file "%s" is not a file.', $originFile));
|
||||
throw new FileNotFoundException(\sprintf('Origin file "%s" is not a file.', $originFile));
|
||||
}
|
||||
|
||||
foreach ($this->toIterable($targetFiles) as $targetFile) {
|
||||
@@ -405,10 +416,10 @@ class Filesystem
|
||||
{
|
||||
if (self::$lastError) {
|
||||
if ('\\' === \DIRECTORY_SEPARATOR && str_contains(self::$lastError, 'error code(1314)')) {
|
||||
throw new IOException(sprintf('Unable to create "%s" link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target);
|
||||
throw new IOException(\sprintf('Unable to create "%s" link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target);
|
||||
}
|
||||
}
|
||||
throw new IOException(sprintf('Failed to create "%s" link from "%s" to "%s": ', $linkType, $origin, $target).self::$lastError, 0, null, $target);
|
||||
throw new IOException(\sprintf('Failed to create "%s" link from "%s" to "%s": ', $linkType, $origin, $target).self::$lastError, 0, null, $target);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -445,11 +456,11 @@ class Filesystem
|
||||
public function makePathRelative(string $endPath, string $startPath): string
|
||||
{
|
||||
if (!$this->isAbsolutePath($startPath)) {
|
||||
throw new InvalidArgumentException(sprintf('The start path "%s" is not absolute.', $startPath));
|
||||
throw new InvalidArgumentException(\sprintf('The start path "%s" is not absolute.', $startPath));
|
||||
}
|
||||
|
||||
if (!$this->isAbsolutePath($endPath)) {
|
||||
throw new InvalidArgumentException(sprintf('The end path "%s" is not absolute.', $endPath));
|
||||
throw new InvalidArgumentException(\sprintf('The end path "%s" is not absolute.', $endPath));
|
||||
}
|
||||
|
||||
// Normalize separators on Windows
|
||||
@@ -530,14 +541,14 @@ class Filesystem
|
||||
*
|
||||
* @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 = [])
|
||||
{
|
||||
$targetDir = rtrim($targetDir, '/\\');
|
||||
$originDir = rtrim($originDir, '/\\');
|
||||
$originDirLen = \strlen($originDir);
|
||||
|
||||
if (!$this->exists($originDir)) {
|
||||
throw new IOException(sprintf('The origin directory specified "%s" was not found.', $originDir), 0, null, $originDir);
|
||||
throw new IOException(\sprintf('The origin directory specified "%s" was not found.', $originDir), 0, null, $originDir);
|
||||
}
|
||||
|
||||
// Iterate in destination folder to remove obsolete entries
|
||||
@@ -581,7 +592,7 @@ class Filesystem
|
||||
} elseif (is_file($file)) {
|
||||
$this->copy($file, $target, $options['override'] ?? false);
|
||||
} else {
|
||||
throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
|
||||
throw new IOException(\sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -659,7 +670,7 @@ class Filesystem
|
||||
public function dumpFile(string $filename, $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__));
|
||||
}
|
||||
|
||||
$dir = \dirname($filename);
|
||||
@@ -680,14 +691,18 @@ class Filesystem
|
||||
|
||||
try {
|
||||
if (false === self::box('file_put_contents', $tmpFile, $content)) {
|
||||
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);
|
||||
} finally {
|
||||
if (file_exists($tmpFile)) {
|
||||
if ('\\' === \DIRECTORY_SEPARATOR && !is_writable($tmpFile)) {
|
||||
self::box('chmod', $tmpFile, self::box('fileperms', $tmpFile) | 0200);
|
||||
}
|
||||
|
||||
self::box('unlink', $tmpFile);
|
||||
}
|
||||
}
|
||||
@@ -706,7 +721,7 @@ class Filesystem
|
||||
public function appendToFile(string $filename, $content/* , bool $lock = false */)
|
||||
{
|
||||
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__));
|
||||
}
|
||||
|
||||
$dir = \dirname($filename);
|
||||
@@ -718,7 +733,7 @@ class Filesystem
|
||||
$lock = \func_num_args() > 2 && func_get_arg(2);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -740,7 +755,7 @@ class Filesystem
|
||||
private static function assertFunctionExists(string $func): void
|
||||
{
|
||||
if (!\function_exists($func)) {
|
||||
throw new IOException(sprintf('Unable to perform filesystem operation because the "%s()" function has been disabled.', $func));
|
||||
throw new IOException(\sprintf('Unable to perform filesystem operation because the "%s()" function has been disabled.', $func));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user