50 lines
1.5 KiB
PHP
50 lines
1.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Uploads\Services;
|
|
|
|
use Illuminate\Support\Facades\File;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use RuntimeException;
|
|
|
|
final class FileMoveService
|
|
{
|
|
/**
|
|
* Copy draft directory to final location using staging dir; source remains untouched.
|
|
*/
|
|
public function promoteDraft(string $uploadId, string $targetRelativeDir): void
|
|
{
|
|
$disk = Storage::disk('local');
|
|
|
|
$sourceRelativeDir = 'tmp/drafts/' . $uploadId;
|
|
if (! $disk->exists($sourceRelativeDir)) {
|
|
throw new RuntimeException('Draft directory not found.');
|
|
}
|
|
|
|
$targetRelativeDir = trim($targetRelativeDir, '/');
|
|
$stagingRelativeDir = $targetRelativeDir . '.__staging';
|
|
|
|
if ($disk->exists($targetRelativeDir)) {
|
|
throw new RuntimeException('Target publish directory already exists.');
|
|
}
|
|
|
|
if ($disk->exists($stagingRelativeDir)) {
|
|
$disk->deleteDirectory($stagingRelativeDir);
|
|
}
|
|
|
|
$sourceAbs = $disk->path($sourceRelativeDir);
|
|
$stagingAbs = $disk->path($stagingRelativeDir);
|
|
$targetAbs = $disk->path($targetRelativeDir);
|
|
|
|
if (! File::copyDirectory($sourceAbs, $stagingAbs)) {
|
|
throw new RuntimeException('Failed to stage files for publish.');
|
|
}
|
|
|
|
if (! File::moveDirectory($stagingAbs, $targetAbs, false)) {
|
|
$disk->deleteDirectory($stagingRelativeDir);
|
|
throw new RuntimeException('Failed to move staged files to final location.');
|
|
}
|
|
}
|
|
}
|