refactor: front end
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -7,20 +7,17 @@ declare(strict_types=1);
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace KTXM\FileManager\Controllers;
|
||||
namespace KTXM\DocumentsManager\Controllers;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use KTXC\Http\Response\JsonResponse;
|
||||
use KTXC\Http\Response\Response;
|
||||
use KTXC\Http\Response\StreamedResponse;
|
||||
use KTXC\SessionIdentity;
|
||||
use KTXC\SessionTenant;
|
||||
use KTXF\Controller\ControllerAbstract;
|
||||
use KTXF\Files\Node\INodeCollectionBase;
|
||||
use KTXF\Files\Node\INodeEntityBase;
|
||||
use KTXF\Routing\Attributes\AuthenticatedRoute;
|
||||
use KTXM\FileManager\Manager;
|
||||
use KTXM\FileManager\Transfer\StreamingZip;
|
||||
use KTXM\DocumentsManager\Manager;
|
||||
use KTXM\DocumentsManager\Transfer\StreamingZip;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
|
||||
@@ -39,7 +36,7 @@ class TransferController extends ControllerAbstract
|
||||
public function __construct(
|
||||
private readonly SessionTenant $tenantIdentity,
|
||||
private readonly SessionIdentity $userIdentity,
|
||||
private Manager $fileManager,
|
||||
private readonly Manager $manager,
|
||||
private readonly LoggerInterface $logger
|
||||
) {}
|
||||
|
||||
@@ -50,21 +47,16 @@ class TransferController extends ControllerAbstract
|
||||
*/
|
||||
#[AuthenticatedRoute(
|
||||
'/download/entity/{provider}/{service}/{collection}/{identifier}',
|
||||
name: 'filemanager.download.entity',
|
||||
name: 'document_manager.download.entity',
|
||||
methods: ['GET']
|
||||
)]
|
||||
public function downloadEntity(
|
||||
string $provider,
|
||||
string $service,
|
||||
string $collection,
|
||||
string $identifier
|
||||
): Response {
|
||||
public function downloadEntity(string $provider, string $service, string $collection, string $identifier): Response {
|
||||
$tenantId = $this->tenantIdentity->identifier();
|
||||
$userId = $this->userIdentity->identifier();
|
||||
|
||||
try {
|
||||
// Fetch entity metadata
|
||||
$entities = $this->fileManager->entityFetch(
|
||||
$entities = $this->manager->entityFetch(
|
||||
$tenantId,
|
||||
$userId,
|
||||
$provider,
|
||||
@@ -80,11 +72,10 @@ class TransferController extends ControllerAbstract
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
/** @var INodeEntityBase $entity */
|
||||
$entity = $entities[$identifier];
|
||||
|
||||
// Get the stream
|
||||
$stream = $this->fileManager->entityReadStream(
|
||||
$stream = $this->manager->entityReadStream(
|
||||
$tenantId,
|
||||
$userId,
|
||||
$provider,
|
||||
@@ -100,22 +91,29 @@ class TransferController extends ControllerAbstract
|
||||
], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$filename = $entity->getLabel() ?? 'download';
|
||||
$mime = $entity->getMime() ?? 'application/octet-stream';
|
||||
$size = $entity->size();
|
||||
$filename = $entity->getProperties()->getLabel() ?? 'download';
|
||||
$mime = $entity->getProperties()->getMime() ?? 'application/octet-stream';
|
||||
$size = $entity->getProperties()->size();
|
||||
|
||||
// Create streamed response
|
||||
$response = new StreamedResponse(function () use ($stream) {
|
||||
while (!feof($stream)) {
|
||||
echo fread($stream, 65536);
|
||||
@ob_flush();
|
||||
flush();
|
||||
try {
|
||||
while (!feof($stream)) {
|
||||
echo fread($stream, 65536);
|
||||
@ob_flush();
|
||||
flush();
|
||||
}
|
||||
} finally {
|
||||
fclose($stream);
|
||||
}
|
||||
fclose($stream);
|
||||
});
|
||||
|
||||
$response->headers->set('Content-Type', $mime);
|
||||
$response->headers->set('Content-Length', (string) $size);
|
||||
// Only advertise Content-Length when metadata is non-zero; a zero value
|
||||
// would cause clients to believe the file is empty and discard the body.
|
||||
if ($size > 0) {
|
||||
$response->headers->set('Content-Length', (string) $size);
|
||||
}
|
||||
$response->headers->set('Content-Disposition',
|
||||
$response->headers->makeDisposition('attachment', $filename, $this->asciiFallback($filename))
|
||||
);
|
||||
@@ -139,16 +137,10 @@ class TransferController extends ControllerAbstract
|
||||
*/
|
||||
#[AuthenticatedRoute(
|
||||
'/download/archive',
|
||||
name: 'filemanager.download.archive',
|
||||
name: 'manager.download.archive',
|
||||
methods: ['GET']
|
||||
)]
|
||||
public function downloadArchive(
|
||||
string $provider,
|
||||
string $service,
|
||||
array $ids = [],
|
||||
string $collection = null,
|
||||
string $name = 'download'
|
||||
): Response {
|
||||
public function downloadArchive(string $provider, string $service, array $ids = [], ?string $collection = null, string $name = 'download'): Response {
|
||||
$tenantId = $this->tenantIdentity->identifier();
|
||||
$userId = $this->userIdentity->identifier();
|
||||
|
||||
@@ -184,7 +176,7 @@ class TransferController extends ControllerAbstract
|
||||
$zip = new StreamingZip(null, false); // No compression for speed
|
||||
|
||||
foreach ($files as $file) {
|
||||
$stream = $this->fileManager->entityReadStream(
|
||||
$stream = $this->manager->entityReadStream(
|
||||
$tenantId,
|
||||
$userId,
|
||||
$provider,
|
||||
@@ -194,12 +186,15 @@ class TransferController extends ControllerAbstract
|
||||
);
|
||||
|
||||
if ($stream !== null) {
|
||||
$zip->addFileFromStream(
|
||||
$file['path'],
|
||||
$stream,
|
||||
$file['modTime'] ?? null
|
||||
);
|
||||
fclose($stream);
|
||||
try {
|
||||
$zip->addFileFromStream(
|
||||
$file['path'],
|
||||
$stream,
|
||||
$file['modTime'] ?? null
|
||||
);
|
||||
} finally {
|
||||
fclose($stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,20 +226,17 @@ class TransferController extends ControllerAbstract
|
||||
*/
|
||||
#[AuthenticatedRoute(
|
||||
'/download/collection/{provider}/{service}/{identifier}',
|
||||
name: 'filemanager.download.collection',
|
||||
name: 'manager.download.collection',
|
||||
methods: ['GET']
|
||||
)]
|
||||
public function downloadCollection(
|
||||
string $provider,
|
||||
string $service,
|
||||
string $identifier
|
||||
): Response {
|
||||
public function downloadCollection(string $provider, string $service, string $identifier): Response {
|
||||
$tenantId = $this->tenantIdentity->identifier();
|
||||
$userId = $this->userIdentity->identifier();
|
||||
|
||||
try {
|
||||
// Fetch collection metadata
|
||||
$collection = $this->fileManager->collectionFetch(
|
||||
/** @var CollectionBaseInterface|null $collection */
|
||||
$collection = $this->manager->collectionFetch(
|
||||
$tenantId,
|
||||
$userId,
|
||||
$provider,
|
||||
@@ -280,7 +272,7 @@ class TransferController extends ControllerAbstract
|
||||
if ($file['type'] === 'directory') {
|
||||
$zip->addDirectory($file['path'], $file['modTime'] ?? null);
|
||||
} else {
|
||||
$stream = $this->fileManager->entityReadStream(
|
||||
$stream = $this->manager->entityReadStream(
|
||||
$tenantId,
|
||||
$userId,
|
||||
$provider,
|
||||
@@ -290,12 +282,15 @@ class TransferController extends ControllerAbstract
|
||||
);
|
||||
|
||||
if ($stream !== null) {
|
||||
$zip->addFileFromStream(
|
||||
$file['path'],
|
||||
$stream,
|
||||
$file['modTime'] ?? null
|
||||
);
|
||||
fclose($stream);
|
||||
try {
|
||||
$zip->addFileFromStream(
|
||||
$file['path'],
|
||||
$stream,
|
||||
$file['modTime'] ?? null
|
||||
);
|
||||
} finally {
|
||||
fclose($stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -323,20 +318,14 @@ class TransferController extends ControllerAbstract
|
||||
/**
|
||||
* Resolve a list of entity/collection IDs into a flat file list for archiving
|
||||
*/
|
||||
private function resolveFilesForArchive(
|
||||
string $tenantId,
|
||||
string $userId,
|
||||
string $provider,
|
||||
string $service,
|
||||
?string $collection,
|
||||
array $ids
|
||||
): array {
|
||||
private function resolveFilesForArchive(string $tenantId, string $userId, string $provider, string $service, ?string $collection, array $ids): array {
|
||||
$files = [];
|
||||
|
||||
foreach ($ids as $id) {
|
||||
// Try as entity first
|
||||
if ($collection !== null) {
|
||||
$entities = $this->fileManager->entityFetch(
|
||||
/** @var EntityBaseInterface[] $entities */
|
||||
$entities = $this->manager->entityFetch(
|
||||
$tenantId,
|
||||
$userId,
|
||||
$provider,
|
||||
@@ -346,7 +335,6 @@ class TransferController extends ControllerAbstract
|
||||
);
|
||||
|
||||
if (!empty($entities) && isset($entities[$id])) {
|
||||
/** @var INodeEntityBase $entity */
|
||||
$entity = $entities[$id];
|
||||
$files[] = [
|
||||
'type' => 'file',
|
||||
@@ -360,7 +348,8 @@ class TransferController extends ControllerAbstract
|
||||
}
|
||||
|
||||
// Try as collection (folder)
|
||||
$collectionNode = $this->fileManager->collectionFetch(
|
||||
/** @var CollectionBaseInterface|null $collectionNode */
|
||||
$collectionNode = $this->manager->collectionFetch(
|
||||
$tenantId,
|
||||
$userId,
|
||||
$provider,
|
||||
@@ -394,10 +383,21 @@ class TransferController extends ControllerAbstract
|
||||
string $provider,
|
||||
string $service,
|
||||
string $collectionId,
|
||||
string $basePath
|
||||
string $basePath,
|
||||
int $depth = 0,
|
||||
int $maxDepth = 20
|
||||
): array {
|
||||
$files = [];
|
||||
|
||||
// Guard against runaway recursion on pathologically deep trees
|
||||
if ($depth > $maxDepth) {
|
||||
$this->logger->warning('Max recursion depth reached, skipping deeper contents', [
|
||||
'collection' => $collectionId,
|
||||
'depth' => $depth,
|
||||
]);
|
||||
return $files;
|
||||
}
|
||||
|
||||
// Add directory entry if we have a path
|
||||
if ($basePath !== '') {
|
||||
$files[] = [
|
||||
@@ -410,7 +410,7 @@ class TransferController extends ControllerAbstract
|
||||
// Get all nodes in this collection using nodeList with recursive=false
|
||||
// We handle recursion ourselves to build proper paths
|
||||
try {
|
||||
$nodes = $this->fileManager->nodeList(
|
||||
$nodes = $this->manager->nodeList(
|
||||
$tenantId,
|
||||
$userId,
|
||||
$provider,
|
||||
@@ -438,7 +438,9 @@ class TransferController extends ControllerAbstract
|
||||
$provider,
|
||||
$service,
|
||||
(string) $node->id(),
|
||||
$nodePath
|
||||
$nodePath,
|
||||
$depth + 1,
|
||||
$maxDepth
|
||||
);
|
||||
$files = array_merge($files, $subFiles);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user