This section describes the modern way to interact with files and folders in Contao. Please note, the legacy classes
\Contao\File
, \Contao\Folder
, \Contao\FilesModel
and \Contao\Dbafs
still work, but aren’t covered here.
This feature is available in Contao 4.13 and later.
The new filesystem capabilities are currently considered experimental and therefore not covered by Contao’s BC
promise. Classes marked with @experimental
should be considered internal for now. Although not likely, there could
also be some behavioral changes, so be prepared.
Our filesystem implementation is an abstraction for the real filesystem based on the popular Flysystem. With Flysystem we can interface with different storage adapters behind the scenes: in the simplest form this is your local filesystem, but it could for instance also be a Dropbox share, an AWS bucket or an FTP remote.
We’re composing these storage adapters in a MountManager
by mounting each adapter under a certain path. So, if you
access a file files/images/cat.jpg
, we might not look at your local filesystem, but deliver the file cat.jpg
from
your Dropbox adapter which was mounted under files/images
. Both sides are decoupled, which offers a great flexibility
in configuring the system: The code consuming the image does not need to know about the used adapter and the adapter
does not need to know anything about the filesystem structure it sits in. The idea behind this abstraction is to allow
both extensions as well as the application to reconfigure and outsource the filesystem without the need to change any
code.
In a CMS context, we also want to enrich some of our files with extra metadata. Say, author, license, alt and caption
information for images or maybe searchable attributes for your documents. We can store this information in a database
table like tl_files
but then we need to make sure both sources - database and filesystem - are in sync. This is no
easy task, but we built a DBAFS (Database assisted filesystem) service that does exactly that. And because you can now
have more than one DBAFS, there is a DbafsManager
instance that leverages access to the individual services similar to
the MountManager
. Each resource stored in the database can also be accessed by a globally unique identifier, a
UUID. For that reason, UUIDs are a first level citizen in the DbafsManager
when accessing resources.
The filesystem is a complex machinery under the hood, but we got you covered. We build the Virtual Filesystem, an abstraction that allows to read and write files without the need to know any internals. See the Virtual filesystem section for real world examples on how to use the system.
Component | What is it good for? | Abstraction level |
---|---|---|
VirtualFilesystem | Your primary gateway to read and write resources from the filesystem, that uses the MountManager and DbafsManager under the hood. | high |
MountManager | Service, that allows to read from and write to a filesystem adapter whose mount path matches the resource’s path prefix. Read more about mounting your own adapters in the Config section. | low |
DbafsManager | Service, that allows to access and modify metadata of a DBAFS that matches the resource’s path prefix or UUID. Read more about setting up your own DBAFS service in the Config section. | low |
In an application, there will typically be one MountManager
and one DbafsManager
but multiple virtual
filesystems. Each virtual filesystem instance can be scoped to a certain path and can be set to disallow modifications
(readonly mode). In Contao we’re for instance already shipping a $filesStorage
and a $backupsStorage
that are scoped
to /files
and /backups
.