add site to view and upload files

Reviewed-on: sites/file-explorer#4
This commit is contained in:
2024-12-05 09:42:25 +00:00
parent 1ec2ed1d00
commit bf226d7e3f
31 changed files with 2178 additions and 6 deletions

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class EntrypointController extends AbstractController
{
#[Route(path: '/', name: 'app_root', methods: Request::METHOD_GET)]
public function __invoke(): Response
{
return $this->redirectToRoute('app_home');
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Controller;
use App\Forms\UploadFileForm;
use App\Service\FileSystemService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class HomeController extends AbstractController
{
#[Route(path: '/files', name: 'app_home', methods: [Request::METHOD_GET])]
public function __invoke(FileSystemService $fileSystemService): Response
{
return $this->render('home.html.twig', [
'content' => $fileSystemService->getDirs(),
'fileForm' => $this->createForm(UploadFileForm::class),
]);
}
}

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Forms\UploadFileForm;
use App\Objects\UploadedFileData;
use App\Service\FileSystemService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class UploadController extends AbstractController
{
#[Route(path: '/upload', name: 'app_upload', methods: Request::METHOD_POST)]
public function __invoke(
FileSystemService $fileSystemService,
Request $request,
): Response
{
$fileData = new UploadedFileData();
$form = $this->createForm(UploadFileForm::class, $fileData)->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$fileSystemService->uploadFile($fileData->file);
}
return $this->redirectToRoute('app_home');
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Forms;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class UploadFileForm extends AbstractType
{
public function __construct(private readonly UrlGeneratorInterface $urlGenerator)
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setAction($this->urlGenerator->generate('app_upload'))
->add('file', FileType::class, [
'attr' => ['class' => 'hidden'],
'multiple' => true,
]);
}
}

View File

@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace App\Objects;
use SplFileInfo;
class DirContent
{
private function __construct(
private readonly string $name,
private readonly int $size,
private readonly string $type,
)
{
}
public static function make(SplFileInfo $fileInfo): DirContent
{
return new self(
$fileInfo->getBasename(),
$fileInfo->getSize() ?? 0,
$fileInfo->getType() ?? 'N/A',
);
}
public function getName(): string
{
return $this->name;
}
public function getSize(bool $humanReadable = true): int|string
{
if (!$humanReadable) {
return $this->size;
}
return $this->getHumanReadableSize();
}
public function getType(): string
{
return $this->type;
}
private function getHumanReadableSize()
{
$bytes = $this->size;
$size = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
$factor = floor((strlen((string) $bytes) - 1) / 3);
return sprintf("%.1f %s", $bytes / (1024 ** $factor), $size[$factor]);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Objects;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class UploadedFileData
{
/**
* @var UploadedFile[] $file
*/
public array $file;
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Service;
use App\Objects\DirContent;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FileSystemService
{
public function __construct(
#[Autowire(env: 'DATA_DIR')]
private readonly string $dir,
private readonly Filesystem $filesystem,
) {
}
/**
* @return DirContent[]
*/
public function getDirs(): array
{
$finder = new Finder();
$finder->in($this->dir);
$contents = [];
foreach ($finder->depth(0) as $content) {
$contents[] = DirContent::make($content);
}
return $contents;
}
/**
* @param UploadedFile[] $files
*/
public function uploadFile(array $files): void
{
foreach ($files as $file) {
$this->filesystem->dumpFile($this->dir . '/' . $file->getClientOriginalName(), $file->getContent());
}
}
}