Skip to content

Commit

Permalink
Merge branch 'artgris:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
xDeSwa committed Aug 31, 2024
2 parents ef6ca93 + 5df601c commit e5e49f4
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 61 deletions.
14 changes: 12 additions & 2 deletions Controller/ManagerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
Expand Down Expand Up @@ -275,8 +277,16 @@ public function uploadFileAction(Request $request): JsonResponse|Response {
#[Route("/file/{fileName}", name: 'file_manager_file')]
public function binaryFileResponseAction(Request $request, string $fileName): BinaryFileResponse {
$fileManager = $this->newFileManager($request->query->all());
$configuredDirectory = $fileManager->getConfiguration()['dir'];

$file = $fileManager->getCurrentPath().\DIRECTORY_SEPARATOR.urldecode($fileName);
$realFilePath = realpath($file);
if (false === $realFilePath) {
throw new FileNotFoundException($file);
}
if (!str_starts_with($realFilePath, realpath($configuredDirectory))) {
throw new BadRequestHttpException('Accessing outside configured directory is not allowed.');
}
$this->dispatch(FileManagerEvents::FILE_ACCESS, ['path' => $file]);

return new BinaryFileResponse($file);
Expand Down Expand Up @@ -327,7 +337,7 @@ public function deleteAction(Request $request): RedirectResponse {
}

$this->dispatch(FileManagerEvents::POST_DELETE_FOLDER);
$queryParameters['route'] = \dirname($fileManager->getCurrentRoute());
$queryParameters['route'] = \dirname($fileManager->getRoute());
if ($queryParameters['route'] == '/') {
unset($queryParameters['route']);
}
Expand Down Expand Up @@ -409,7 +419,7 @@ private function retrieveSubDirectories(FileManager $fileManager, string $path,
'href' => $fileName ? $this->generateUrl('file_manager', $queryParameters) : $this->generateUrl('file_manager', $queryParametersRoute),
],
'state' => [
'selected' => $fileManager->getCurrentRoute() === $fileName,
'selected' => $fileManager->getRoute() === $fileName,
'opened' => true,
],
];
Expand Down
8 changes: 6 additions & 2 deletions DependencyInjection/ArtgrisFileManagerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@
*/
class ArtgrisFileManagerExtension extends Extension
{
public function getConfiguration(array $config, ContainerBuilder $container): Configuration
{
return new Configuration($container->getParameter('kernel.project_dir'));
}

/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container): void
{

$configuration = new Configuration($container->getParameter('kernel.project_dir'));
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);

$container->setParameter('artgris_file_manager', $config);
Expand Down
2 changes: 1 addition & 1 deletion Helpers/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function __construct(private SplFileInfo $file,private TranslatorInterfac
* @return array|false|string
*/
public function getDimension(): bool|array|string {
return preg_match('/(gif|png|jpe?g|svg)$/i', $this->file->getExtension()) ?
return preg_match('/(gif|png|jpe?g|svg|webp)$/i', $this->file->getExtension()) ?
@getimagesize($this->file->getPathname()) : '';
}

Expand Down
115 changes: 73 additions & 42 deletions Helpers/FileManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,60 +13,66 @@
/**
* @author Arthur Gribet <[email protected]>
*/
class FileManager {
class FileManager
{
const VIEW_THUMBNAIL = 'thumbnail';
const VIEW_LIST = 'list';

/**
* FileManager constructor.
*/
public function __construct(private array $queryParameters, private array $configuration, private RouterInterface $router, private EventDispatcherInterface $dispatcher, private string $webDir) {
public function __construct(private array $queryParameters, private array $configuration, private RouterInterface $router, private EventDispatcherInterface $dispatcher, private string $webDir)
{
// Check Security
$this->checkSecurity();
}

public function getDirName(): string {
public function getDirName(): string
{
return \dirname($this->getBasePath());
}

public function getBaseName(): string {
public function getBaseName(): string
{
return basename($this->getBasePath());
}

public function getRegex(): string {
public function getRegex(): string
{
if (isset($this->configuration['regex'])) {
return '/'.$this->configuration['regex'].'/i';
return '/' . $this->configuration['regex'] . '/i';
}

return match ($this->getType()) {
'media' => '/\.(mp4|ogg|webm)$/i',
'image' => '/\.(gif|png|jpe?g|svg)$/i',
'image' => '/\.(gif|png|jpe?g|svg|webp)$/i',
default => '/.+$/i',
};
}

public function getCurrentRoute(): ?string {
if ($this->getRoute()) {
return urldecode($this->getRoute());
}

return null;
}
// public function getCurrentRoute(): ?string {
// if ($this->getRoute()) {
// return urldecode($this->getRoute());
// }
//
// return null;
// }

public function getCurrentPath(): bool|string {
return realpath($this->getBasePath().$this->getCurrentRoute());
public function getCurrentPath(): bool|string
{
return realpath($this->getBasePath() . $this->getRoute());
}

// parent url
public function getParent(): ?string {
public function getParent(): ?string
{
$queryParentParameters = $this->queryParameters;

if ($this->getCurrentRoute()) {

$parentRoute = \dirname($this->getCurrentRoute());
if ($this->getRoute()) {

$parentRoute = \dirname($this->getRoute());
if (\DIRECTORY_SEPARATOR !== $parentRoute) {
$queryParentParameters['route'] = \dirname($this->getCurrentRoute());
$queryParentParameters['route'] = \dirname($this->getRoute());
} else {
unset($queryParentParameters['route']);
}
Expand All @@ -79,28 +85,33 @@ public function getParent(): ?string {
return null;
}

public function getImagePath(): bool|string {
public function getImagePath(): bool|string
{
$baseUrl = $this->getBaseUrl();

if ($baseUrl) {
return $baseUrl.$this->getCurrentRoute().'/';
$routePath = $this->getRoutePath();
return $baseUrl . $routePath . '/';
}

return false;
}

private function getBaseUrl(): bool|string {
private function getBaseUrl(): bool|string
{
$webPath = $this->webDir;
$dirl = new \SplFileInfo($this->getConfiguration()['dir']);
$base = $dirl->getPathname();

if (0 === mb_strpos($base, $webPath)) {
if (str_starts_with($base, $webPath)) {
return mb_substr($base, mb_strlen($webPath));
}

return false;
}

private function checkSecurity(): void {
private function checkSecurity(): void
{
if (!isset($this->configuration['dir'])) {
throw new HttpException(Response::HTTP_INTERNAL_SERVER_ERROR, 'Please define a "dir" parameter in your config.yml');
}
Expand All @@ -115,67 +126,86 @@ private function checkSecurity(): void {
$currentPath = $this->getCurrentPath();

// check Path security
if (false === $currentPath || 0 !== mb_strpos($currentPath, $this->getBasePath())) {
if (false === $currentPath || !str_starts_with($currentPath, $this->getBasePath())) {
throw new HttpException(Response::HTTP_UNAUTHORIZED, 'You are not allowed to access this folder.');
}
$event = new GenericEvent($this, ['path' => $currentPath]);
$this->dispatcher->dispatch($event, FileManagerEvents::POST_CHECK_SECURITY);

}

public function getModule(): ?string {
public function getModule(): ?string
{
return $this->getQueryParameters()['module'] ?? null;
}

public function getType(): ?string {
public function getType(): ?string
{
return $this->mergeConfAndQuery('type');
}

public function getRoute(): ?string {
public function getRoute(): ?string
{
return isset($this->getQueryParameters()['route']) && '/' !== $this->getQueryParameters()['route'] ? $this->getQueryParameters()['route'] : null;
}

public function getBasePath(): bool|string {
public function getRoutePath(): ?string
{
return implode('/', array_map('rawurlencode', explode('/', $this->getRoute())));
}

public function getBasePath(): bool|string
{
return realpath($this->getConfiguration()['dir']);
}

public function getQueryParameters(): array {
public function getQueryParameters(): array
{
return $this->queryParameters;
}

public function getRouter(): RouterInterface {
public function getRouter(): RouterInterface
{
return $this->router;
}

public function setRouter(RouterInterface $router): void {
public function setRouter(RouterInterface $router): void
{
$this->router = $router;
}

public function getConfiguration(): array {
public function getConfiguration(): array
{
return $this->configuration;
}

public function setConfiguration(array $configuration): void {
public function setConfiguration(array $configuration): void
{
$this->configuration = $configuration;
}

public function getTree(): bool {
public function getTree(): bool
{
return $this->mergeQueryAndConf('tree', true);
}

public function getView(): string {
public function getView(): string
{
return $this->mergeQueryAndConf('view', 'list');
}

public function getQueryParameter(string $parameter) {
public function getQueryParameter(string $parameter)
{
return $this->getQueryParameters()[$parameter] ?? null;
}

public function getConfigurationParameter(string $parameter) {
public function getConfigurationParameter(string $parameter)
{
return $this->getConfiguration()[$parameter] ?? null;
}

private function mergeQueryAndConf(string $parameter, $default = null) {
private function mergeQueryAndConf(string $parameter, $default = null)
{
if (null !== $this->getQueryParameter($parameter)) {
return $this->getQueryParameter($parameter);
}
Expand All @@ -186,7 +216,8 @@ private function mergeQueryAndConf(string $parameter, $default = null) {
return $default;
}

private function mergeConfAndQuery(string $parameter, $default = null) {
private function mergeConfAndQuery(string $parameter, $default = null)
{
if (null !== $this->getConfigurationParameter($parameter)) {
return $this->getConfigurationParameter($parameter);
}
Expand Down
2 changes: 1 addition & 1 deletion Resources/doc/book/1-basic-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ artgris_file_manager:

`media`: `/\.(mp4|ogg|webm)$/i` Accept basic HTML video media types (.mp4, .ogg and .webm)

`image:`: `/\.(gif|png|jpe?g|svg)$/i` Accept basic HTML image types (.gif, .png, .jpg, .jpeg and .svg)
`image:`: `/\.(gif|png|jpe?g|svg|webp)$/i` Accept basic HTML image types (.gif, .png, .jpg, .jpeg, .svg and webp)

`file`: `/.+$/i` Accept all files with an extension (.pdf, .html, ...)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
options: {
// The regular expression for the types of images to load:
// matched against the file type:
loadImageFileTypes: /^image\/(gif|jpeg|png|svg\+xml)$/,
loadImageFileTypes: /^image\/(gif|jpeg|png|webp|svg\+xml)$/,
// The maximum file size of images to load:
loadImageMaxFileSize: 10000000, // 10MB
// The maximum width of resized images:
Expand Down
6 changes: 0 additions & 6 deletions Resources/public/libs/jstree/dist/jstree.min.js

This file was deleted.

61 changes: 61 additions & 0 deletions Resources/translations/messages.it.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
file:
add:
success: è stato caricato correttamente
renamed:
success: Il file è stato rinominato correttamente
danger: Il file esiste già o non sei autorizzato a rinominarlo
unauthorized: I file non esistono più o non sei autorizzato ad accedere a questa pagina
nochanged: Nessuna modifica rilevata
deleted:
success: I file sono stati eliminati correttamente
danger: I file non esistono più o non sei autorizzato ad accedere a questa pagina
unauthorized: I file non esistono più o non sei autorizzato ad accedere a questa pagina
folder:
add:
danger: "Si è verificato un errore durante la creazione della cartella: %message%"
success: La cartella è stata creata correttamente
deleted:
success: La cartella è stata eliminata correttamente
unauthorized: La cartella non esiste più o non sei autorizzato ad accedere a questa pagina
button:
cancel: ANNULLA
refresh: Aggiorna
parent: Genitore
save: SALVA
add:
files: Aggiungi file...
folder: Nuova cartella...
delete:
current: Elimina cartella corrente
selected: Elimina file selezionati
action: ELIMINA
rename:
action: RINOMINA
tree: Albero
title:
add:
folder: Nuova cartella
rename:
file: Rinomina
delete: Elimina
download: Scarica
preview:
file: Apri
input:
default: Cartella senza titolo
table:
name: Nome
date: Data
size: Peso
dimension: Dimensione
actions: Azioni
confirm:
delete: Sei sicuro di voler eliminare?
size:
mb: MB
kb: kB
select-all: Seleziona tutto
upload:
exception_move_uploaded_file: Permesso negato
search:
placeholder: Cerca
Loading

0 comments on commit e5e49f4

Please sign in to comment.