mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-02 22:35:43 +08:00
Add moveFileOrDir method to handle cross-device file and directory moves
This commit is contained in:
31
src/Package/Artifact/imagick.php
Normal file
31
src/Package/Artifact/imagick.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Package\Artifact;
|
||||
|
||||
use StaticPHP\Attribute\Artifact\AfterSourceExtract;
|
||||
use StaticPHP\Attribute\PatchDescription;
|
||||
use StaticPHP\Util\SourcePatcher;
|
||||
|
||||
class imagick
|
||||
{
|
||||
#[AfterSourceExtract('ext-imagick')]
|
||||
#[PatchDescription('Patch imagick for PHP 8.4 compatibility (versions < 3.8.0)')]
|
||||
public function patchImagickWith84(): void
|
||||
{
|
||||
// match imagick version id
|
||||
$file = SOURCE_PATH . '/php-src/ext/imagick/php_imagick.h';
|
||||
if (!file_exists($file)) {
|
||||
return;
|
||||
}
|
||||
$content = file_get_contents($file);
|
||||
if (preg_match('/#define PHP_IMAGICK_EXTNUM\s+(\d+)/', $content, $match) === 0) {
|
||||
return;
|
||||
}
|
||||
$extnum = intval($match[1]);
|
||||
if ($extnum < 30800) {
|
||||
SourcePatcher::patchFile('imagick_php84_before_30800.patch', SOURCE_PATH . '/php-src/ext/imagick');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -493,6 +493,44 @@ class FileSystem
|
||||
return FileSystem::convertPath($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move file or directory, handling cross-device scenarios
|
||||
* Uses rename() if possible, falls back to copy+delete for cross-device moves
|
||||
*
|
||||
* @param string $source Source path
|
||||
* @param string $dest Destination path
|
||||
*/
|
||||
public static function moveFileOrDir(string $source, string $dest): void
|
||||
{
|
||||
$source = FileSystem::convertPath($source);
|
||||
$dest = FileSystem::convertPath($dest);
|
||||
|
||||
// Check if source and dest are on the same device to avoid cross-device rename errors
|
||||
$source_stat = @stat($source);
|
||||
$dest_parent = dirname($dest);
|
||||
$dest_stat = @stat($dest_parent);
|
||||
|
||||
// Only use rename if on same device
|
||||
if ($source_stat !== false && $dest_stat !== false && $source_stat['dev'] === $dest_stat['dev']) {
|
||||
if (@rename($source, $dest)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to copy + delete for cross-device moves or if rename failed
|
||||
if (is_dir($source)) {
|
||||
FileSystem::copyDir($source, $dest);
|
||||
FileSystem::removeDir($source);
|
||||
} else {
|
||||
if (!copy($source, $dest)) {
|
||||
throw new FileSystemException("Failed to copy file from {$source} to {$dest}");
|
||||
}
|
||||
if (!unlink($source)) {
|
||||
throw new FileSystemException("Failed to remove source file: {$source}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function replaceFile(string $filename, int $replace_type = REPLACE_FILE_STR, mixed $callback_or_search = null, mixed $to_replace = null): false|int
|
||||
{
|
||||
logger()->debug('Replacing file with type[' . $replace_type . ']: ' . $filename);
|
||||
|
||||
Reference in New Issue
Block a user