mirror of
https://github.com/brufdev/many-notes.git
synced 2026-05-14 22:28:26 -05:00
78 lines
2.3 KiB
PHP
78 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Actions;
|
|
|
|
use App\Models\Vault;
|
|
use App\Models\VaultNode;
|
|
use Exception;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
use Staudenmeir\LaravelAdjacencyList\Eloquent\Collection;
|
|
use ZipArchive;
|
|
|
|
final readonly class ExportVault
|
|
{
|
|
public function handle(Vault $vault): string
|
|
{
|
|
$zip = new ZipArchive();
|
|
$relativePath = 'public/' . Str::random(16) . '.zip';
|
|
$path = Storage::disk('local')->path($relativePath);
|
|
$nodes = $vault->nodes()->whereNull('parent_id')->get();
|
|
|
|
if ($nodes->count() === 0) {
|
|
throw new Exception(__('Your vault is empty'));
|
|
}
|
|
|
|
Storage::disk('local')->put($relativePath, '');
|
|
|
|
if ($zip->open($path, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
|
|
throw new Exception(__('Something went wrong'));
|
|
}
|
|
|
|
$this->exportNodes($zip, $nodes);
|
|
$zip->close();
|
|
|
|
return $path;
|
|
}
|
|
|
|
/**
|
|
* @param Collection<int, VaultNode> $nodes
|
|
*/
|
|
private function exportNodes(ZipArchive &$zip, Collection $nodes, string $path = ''): void
|
|
{
|
|
foreach ($nodes as $node) {
|
|
$nodePath = mb_ltrim("$path/$node->name", '/');
|
|
$nodePath .= $node->is_file ? ".$node->extension" : '';
|
|
$relativePath = new GetPathFromVaultNode()->handle($node);
|
|
|
|
if (!Storage::disk('local')->exists($relativePath)) {
|
|
throw new Exception(
|
|
sprintf(
|
|
"%s missing on disk: {$nodePath}",
|
|
$node->is_file ? 'File' : 'Folder',
|
|
),
|
|
);
|
|
}
|
|
|
|
if (!$node->is_file) {
|
|
$zip->addEmptyDir($nodePath);
|
|
|
|
if ($node->children()->count()) {
|
|
$this->exportNodes($zip, $node->children()->get(), $nodePath);
|
|
}
|
|
} elseif ($node->extension === 'md') {
|
|
$zip->addFromString($nodePath, (string) $node->content);
|
|
} else {
|
|
$relativePath = new GetPathFromVaultNode()->handle($node);
|
|
|
|
$zip->addFile(
|
|
Storage::disk('local')->path($relativePath),
|
|
$nodePath,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|