digitalkaoz/gaufrette-browser-bundle
Installation Add the bundle via Composer:
composer require digitalkaoz/gaufrette-browser-bundle
Register the bundle in config/bundles.php (Symfony 4+):
return [
// ...
Digitalkaoz\GaufretteBrowserBundle\DigitalkaozGaufretteBrowserBundle::class => ['all' => true],
];
Configure Gaufrette
Ensure you have a Gaufrette filesystem configured (e.g., in config/packages/gaufrette.yaml):
gaufrette:
filesystems:
my_filesystem:
adapter: local
options:
directory: '%kernel.project_dir%/var/files'
First Use Case: Basic File Browsing
Inject the GaufretteBrowser service into a controller or service:
use Digitalkaoz\GaufretteBrowserBundle\GaufretteBrowser;
class FileController extends AbstractController
{
public function browse(GaufretteBrowser $browser)
{
$files = $browser->getFilesystem('my_filesystem')->getFiles();
// Render files in a template (e.g., Twig)
}
}
Template Integration Use Twig to iterate over files:
{% for file in files %}
<a href="{{ path('file_download', {'id': file.name}) }}">{{ file.name }}</a>
{% endfor %}
File Listing and Navigation
getFilesystem() to access a configured filesystem.getFiles(), getDirectories(), or getDirectory() to traverse the filesystem:
$files = $browser->getFilesystem('my_filesystem')->getDirectory('/subfolder')->getFiles();
File Metadata Handling
getMetadata():
$metadata = $browser->getFilesystem('my_filesystem')->getMetadata('file.txt');
Integration with Doctrine-like ORM
ObjectRepository pattern. Extend Digitalkaoz\GaufretteBrowserBundle\Entity\File to add custom logic:
class CustomFile extends File
{
public function getHumanReadableSize()
{
return $this->getSize() ? size_format($this->getSize()) : '0B';
}
}
Symfony Forms for Uploads
GaufretteBrowser with Symfony’s File type in forms:
$builder->add('file', FileType::class, [
'mapped' => false,
'required' => false,
]);
$filesystem = $browser->getFilesystem('my_filesystem');
$filesystem->write('uploads/' . $file->getClientOriginalName(), file_get_contents($file->getPathname()));
Event Listeners for File Operations
file.pre_upload, file.post_delete) using Symfony’s event dispatcher:
$dispatcher->dispatch(new FileEvent($file), 'file.pre_upload');
Twig Extensions
Create a custom Twig extension to expose GaufretteBrowser methods:
class GaufretteExtension extends \Twig_Extension
{
public function getFunctions()
{
return [
new \Twig_SimpleFunction('list_files', [$this->browser, 'getFiles']),
];
}
}
Register it in services.yaml:
services:
app.twig.gaufrette_extension:
class: App\Twig\GaufretteExtension
arguments: ['@digitalkaoz_gaufrette_browser']
tags: ['twig.extension']
API Endpoints Build RESTful endpoints for file operations:
// src/Controller/FileApiController.php
class FileApiController extends AbstractController
{
public function listFiles(GaufretteBrowser $browser, Request $request)
{
$filesystem = $browser->getFilesystem('my_filesystem');
$path = $request->query->get('path', '/');
$files = $filesystem->getDirectory($path)->getFiles();
return $this->json(array_map(function ($file) {
return [
'name' => $file->getKey(),
'size' => $file->getSize(),
'url' => $this->generateUrl('file_download', ['id' => $file->getKey()]),
];
}, $files));
}
}
Security
// src/Voter/FileVoter.php
class FileVoter extends Voter
{
protected function supports(string $attribute, $subject): bool
{
return $attribute === 'access' && $subject instanceof File;
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
return $token->getUser()->canAccessFile($subject->getKey());
}
}
Deprecated Symfony Versions
api-platform/gaufrette for newer Symfony.Gaufrette Filesystem Configuration
gaufrette.yaml is correctly configured. Missing adapters (e.g., local, s3) will throw exceptions.$adapter = $browser->getFilesystem('my_filesystem')->getAdapter();
var_dump(get_class($adapter));
Entity Mapping Quirks
File entity class. If you extend it, ensure the parent class (Digitalkaoz\GaufretteBrowserBundle\Entity\File) is autoloaded.Entity directory to your autoloader in composer.json:
"autoload": {
"psr-4": {
"Digitalkaoz\\GaufretteBrowserBundle\\": "vendor/digitalkaoz/gaufrette-browser-bundle/src"
}
}
Performance with Large Directories
getFiles() loads all files into memory. For large directories, use pagination or lazy loading:
$directory = $browser->getFilesystem('my_filesystem')->getDirectory('/large-folder');
$files = iterator_to_array($directory->getFiles(), false); // Lazy iteration
Caching Metadata
mtime, size) is fetched on every call. Cache results in a service:
$cache = $this->container->get('cache.app');
$metadata = $cache->get('file_metadata:' . $fileKey, function () use ($browser, $fileKey) {
return $browser->getFilesystem('my_filesystem')->getMetadata($fileKey);
});
Enable Gaufrette Debugging
Add this to config/packages/dev/gaufrette.yaml:
gaufrette:
debug: true
Logs filesystem operations to var/log/dev.log.
Check Filesystem Permissions
chmod -R 755 var/files).www-data for web servers).Validate File Keys
/) as path separators, even on Windows. Avoid backslashes (\) in file keys.Symfony Profiler Integration
GaufretteBrowser service in the profiler to inspect active filesystems:
$this->container->get('debug.stopwatch')->checkPoint('gaufrette_browser');
Custom File Entity
Override the default File entity to add fields (e.g., owner, tags):
namespace App\Entity;
use Digitalkaoz\GaufretteBrowserBundle\Entity\File as BaseFile;
class File extends BaseFile
{
private $owner;
private $tags = [];
// Add getters/setters and Doctrine annotations
}
Register it in services.yaml:
digitalkaoz_gaufrette_browser.file.entity.class: App\Entity\File
Event Subscribers Listen to
How can I help you explore Laravel packages today?