All page names need to be in English.
en da  de  fr  it  ja  km  nl  ru  zh

File Abstraction Layer

From TYPO3Wiki
Jump to: navigation, search

This is the main page describing the file abstraction layer. (TODO: Fill)


FAL supports multiple so-called storages - think of them as harddrives. They are the central entity to manage files and govern all accesses to them. Underneath each storage, there's a driver that does all the dirty work necessary for using the files - but you don't really have to care about that as a user of FAL, as the drivers are nicely encapsulated by the Storage.

Each file in FAL has an identifier, like "/myFolder/myPicture.jpg". This is like a unique path to the file within its storage. The identifier is used to - surprise - identify the file and make it possible for the driver to find it. To make an identifer really unique, it can be prepended with the uid of its storage, followed by a colon, like this: "1:/myFolder/myPicture.jpg".
Additionally, files are indexed in the database (a concept already known from DAM), thus they also get a uid (like every other content in TYPO3). Relations between files and other content are stored in the sys_file_reference table.

When migrating a pre-6.0 TYPO3 installation to 6.0 or newer, a default storage pointing to your fileadmin/ directory is created automatically, so you don't have to do that yourself.

Programming example (in progress)

Here I want to add some programming examples for using FAL in own extension. It is very work in progress as the documentation is still missing and these things stem from bits on the internet and trial and error.

Get a file from a storage

PHP script:
$someFileIdentifier = '/image123.png';          // image name in the storage repository (e.g. directly in fileadmin/ root, otherwise specify the subdirectory here, 'templates/image123.png'
$storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository'); // create instance to storage repository
$storage = $storageRepository->findByUid(1);    // get file storage with uid 1 (this should by default point to your fileadmin/ directory)
$file = $storage->getFile($someFileIdentifier); // create file object for the image (the file will be indexed if necessary)

Get all root files from a storage

PHP script:
$storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository'); // create instance to storage repository
$storage = $storageRepository->findByUid(1);    // get file storage with uid 1 (this should by default point to your fileadmin/ directory)
$files = $storage->getFilesInFolder($storage->getDefaultFolder());

Get file object by combined identifier

Alternatively for getting file direct from specific storage (also gets file from storage 0 = uploads directory/old plugins):

PHP script:
$someFileIdentifier = '1:/user_upload/image.jpg';
$fac = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory'); // create instance to storage repository
$file = $fac->getFileObjectFromCombinedIdentifier($someFileIdentifier);

Index a file / get file by path

The indexing of files is done automatically when using the proper API. If the file is already present in the filesystem you can use the ResourceFactory to the File object for that file:

PHP script:
$filePath = 'fileadmin/user_upload/image.jpg'; // path relative to TYPO3 root
$fileObject = TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($filePath);

If the file isn't present in database it will get indexed (sys_file and sys_file_metadata record is created). When there is already a sys_file record available that info is used to construct the File object.

Add a file

$storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
$storage = $storageRepository->findByUid(1);

$fileObject = $storage->addFile('/tmp/myfile', $storage->getRootLevelFolder(), 'newFile');
echo $fileObject->getIdentifier(); // Should output "/newFile"

Add file reference

PHP script:
$data = array();
$data['sys_file_reference']['NEW1234'] = array(
    'table_local' => 'sys_file',
    'uid_local'   => $file->getUid(),

    'tablenames'  => 'tt_content',
    'uid_foreign' => $tt_content_uid, // uid of your content record
    'fieldname'   => 'image',

    'pid'         => $pages_uid, // page id of content record
$data['tt_content'][$tt_content_uid] = array(
    'image' => 'NEW1234' // changed automatically

/** @var \TYPO3\CMS\Core\DataHandling\DataHandler $tce */
$tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Core\DataHandling\DataHandler'); // create TCE instance
$tce->start($data, array());					 
if ($tce->errorLog) {
    $content .= 'TCE->errorLog:'.t3lib_utility_Debug::viewArray($tce->errorLog);
} else {
    $content .= 'image changed <br>'.t3lib_utility_Debug::viewArray($data);

// Do not directly insert a record into sys_file_reference, as this bypasses all sanity checks and automatic updates done

Get linked images from a content element

$uid = 852250; // content element uid
$fileRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
$fileObjects = $fileRepository->findByRelation('tt_content', 'image', $uid);

// get Imageobject information
$files = array();
foreach ($fileObjects as $key => $value) {
  $files[$key]['reference'] = $value->getReferenceProperties();
  $files[$key]['original'] = $value->getOriginalFile()->getProperties();

foreach ($files as $key => $value) {
  $output .= $value['reference']['name'].'<br>';

Display an image in the frontend

Use the normal cObj Image function but add the parameter file.treatIdAsReference=1 and use a sys_file_reference.uid for the file parameter

// initialize cObj
$this->cObj = t3lib_div::makeInstance("tslib_cObj");

//create image parameter array	
$lconf['image.']['params'] = '';
$lconf["image."]["file."]["treatIdAsReference"] = 1;
$lconf["image."]["file"] = 654983; // sys_file_reference.uid that links a sys_file to e.g. a tt_content element
$lconf['image.']['altText'] = 'altText';
$lconf["image."]["file."]["height"] = "150c";
$lconf["image."]["file."]["width"] = "150c";
$theImgCode = $this->cObj->IMAGE($lconf["image."]);
$image = $this->cObj->stdWrap($theImgCode, $this->conf['image.']); // gets you the html of the image

Generate an image with differing quality settings

The file processing API allows you to set custom ImageMagick/GraphicsMagick parameters in addition to the default parameters (e. g. height, width). The following example generates a 100x100px thumbnail with cropped width and 50% JPEG compression.

$fileObject->process(\TYPO3\CMS\Core\Resource\ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, array(
    'width' => '100c',
    'height' => 100,
    'additionalParameters' => '-quality 50'

Usage in Extbase (in progress)

Extbase ships a File- and a FileReference Model (since TYPO3 6.0) to ease the usage of FAL references in own Extensions. Since TYPO3 6.1 those Models come with a direct access to the reference. Here is an overview how to use it.

This example works with 6.1 only. The configuration allows one file to store (see TCA maxitems setting). To use more files in one field, use an ObjectStorage in the Model.


Method call for default TCA configuration:

'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig('media')

(taken from pages field media)

'header_image' => array(
  'exclude' => 0,
  'label' => 'LLL:EXT:<extkey>/Resources/Private/Language/locallang_db.xlf:<key>',
  'config' => array(
    'maxitems' => 1,
    'type' => 'inline',
    'foreign_table' => 'sys_file_reference',
    'foreign_field' => 'uid_foreign',
    'foreign_sortby' => 'sorting_foreign',
    'foreign_table_field' => 'tablenames',
    'foreign_match_fields' => array(
      'fieldname' => 'header_image'
    'foreign_label' => 'uid_local',
    'foreign_selector' => 'uid_local',
    'foreign_selector_fieldTcaOverride' => array(
      'config' => array(
	'appearance' => array(
	  'elementBrowserType' => 'file',
	  'elementBrowserAllowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
   'filter' => array(
       'userFunc' => 'TYPO3\\CMS\\Core\\Resource\\Filter\\FileExtensionFilter->filterInlineChildren',
       'parameters' => array(
         'allowedFileExtensions' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
         'disallowedFileExtensions' => ''
    'appearance' => array(...)


Since there is no auto configuration available as in TCA, the config has to be done manually.

            <appearance type="array">
                <enabledControls type="array">
                <headerThumbnail type="array">
            <behaviour type="array">
            <filter type="array">

            <foreign_match_fields type="array">
            <foreign_selector_fieldTcaOverride type="array">
                <config type="array">
                    <appearance type="array">

For a complete list of the available options see: TCA Reference - TYPE: inline


 * headerImage
 * @var \TYPO3\CMS\Extbase\Domain\Model\FileReference
 * @lazy
protected $headerImage;

 * sets the HeaderImage
 * @param \TYPO3\CMS\Extbase\Domain\Model\FileReference $headerImage
 * @return void
public function setHeaderImage($headerImage) {
	$this->headerImage = $headerImage;

 * get the HeaderImage
 * @return \TYPO3\CMS\Core\Resource\FileReference
public function getHeaderImage() {
  if (!is_object($this->headerImage)){
    return null;
  } elseif ($this->headerImage instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
  return $this->headerImage->getOriginalResource();


As like with any other IRRE fields, it is possible to use a int field in your ext_tables.sql:

   header_image int(11) unsigned DEFAULT '0' NOT NULL,


<f:image image="{object.headerImage}" alt="{object.headerImage.originalResource.title}" width="150" height="100" />

Use the following if you only have the UID of a file reference:

<f:image src="{object.headerImage.uid}" treatIdAsReference="1" alt="{object.headerImage.originalResource.title}" width="150" height="100" />

FAQ - Frequently Asked Questions

How can I delete files in fileadmin (or any other storage)?

Since TYPO3 6.0.5 there is an option in the file list to delete a file, but only if it is not used anywhere anymore.

How can I access the typolink-field from the meta-data of one file?

10 = FILES
10 {
	references {
		table = tt_content
		uid.field = uid
		fieldName = image
	renderObj = IMAGE
	renderObj { = file:current:publicUrl
		file.height = 340c
		file.width  = 715c = file:current:link

What do the different folders mean?


The default storage (local directory under the TYPO3 site root), and the base for all files related for content manageement. As with each storage, you can configure certain directories in that storage:


The _temp_ directory is automatically added by default when installing TYPO3. Is used for importing / exporting functionality. Is *not* visible from the outside world, as it is protected via .htaccess.

Until 6.0.5, all uploads by the user (see fileadmin/user_upload/) are put in this directory, which is a bug, as files in the folder cannot be accessed by a web browser.


This is the basic default upload folder for all editors for RTE images, for uploading in the Element Browser without choosing a directory. Fixed since TYPO3 6.0.5.


If you have upgraded your installation from TYPO3 4.x, all your files that were previously under /uploads/pics or /uploads/media/ and were connected to ), all files that are in use, are now moved via the Install Tool update wizard to _migrated. This folder is specific only for the migration. You could even sort files out of that directory in other places (via TYPO3, not via FTP or such!), as their locations are now tracked by FAL.


Every time TYPO3 creates a thumbnail or a smaller version for the frontend via ImageMagick, a processed file (sys_file_processed) is created. The files are put in the _processed_ folder - each storage could even rename the folder, so this is not hardcoded. @todo: A cleanup task will remove processed files that are not in use anymore.

Currently (6.0.4) it looks like only the thumbnails are stored here, the smaller frontend tt_content images are stored in typo3temp/_processed_


In versions prior to TYPO3 CMS 6.0, this was the main area when images were uploaded through TCEforms / TCEmain. These days, extensions that don't support FAL still put their files in these directories, which is fine for the time being. With TYPO3 CMS 6.0 all files will stay under any storage, so this TYPO3-managed folder is not needed anymore by the TYPO3 Core, once the update wizards in the Install Tool went through.

This directory should be kept for backwards-compatibility reasons. However, if you are sure that none of your extensions are uploading files (TCA column type=group, internal_type=file - you can search for "uploads/" in the Admin Tools => Configuration module).


This is usually only for temporary files, like cached code files (under typo3temp/Cache/), translation files, and also GIFbuilder images (will be changed in the future), also old RTE magic images.

Currently, there are still some files relevant for the FAL put in there:

  • Preview / Processed images outside of any storage (storageID 0, e.g. preview images from extensions in typo3conf/*)

How can I update files on the server without changing the references in all content elements

A "replace" functionality is still missing.

How to use "levelmedia" with 6.x ?



lib.topimage = IMAGE
lib.topimage {
	file.import = fileadmin/_migrated/media/ = levelmedia: -1,slide
	file.import.listNum = 0
	file.import.override.field = media = page:title


lib.topimage = IMAGE
lib.topimage {
	file.treatIdAsReference = 1 = levelmedia: -1,slide
	file.import.listNum = 0
	file.import.override.field = media = page:title

After with title attribute

10 = FILES
10 {
  references {
    data = levelmedia:-1, slide
  renderObj = COA
  renderObj {
    10 = IMAGE
    10 {
	# import Image = file:current:publicUrl
	# define max width, cropped
	file.width = 430c
	# define max height, cropped
	file.height = 90c
	# define altText = file:current:alternative
	# define titleText = file:current:title
	# get typolink wrapped around IMG-Tag = file:current:link
    20 = TEXT
    20 {
       # define long description = file:current:description
       # wrap description
       stdWrap.wrap = <strong>|</strong>

How to use file collections?

There are two file collections, where the logic is available but the UI is missing.

  • Static file collection = a manually selected group of files
  • folder-based file collection = all files in a specific folder

Both types of file collections are created and edited through the List module of the backend. They can be stored in any page or folder of the page tree.

To render file collections as lists in the frontend you can use the content element File List.

This is how you can use the collections in PHP code:

// fetch all files of a collection with UID $myUid:

// 1. create the collection repository
$collectionRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileCollectionRepository');
$collection = $collectionRepository->findByUid($myUid);

// 2. fetch the records

// 3. loop over the items
$files = $collection->getItems();
foreach ($files as $fileObject) {
// do my thing

How do I configure rights for Backend Users?

Previously, the permission handling for each backend user / group was stored in the DB fields (fileoper_perms), but is now handled via UserTSconfig.

permissions.file.default {
	addFile = 1
	readFile = 1
	editFile = 1
	writeFile = 1
	uploadFile = 1
	copyFile = 1
	moveFile = 1
	renameFile = 1
	unzipFile = 1
	deleteFile = 1

	addFolder = 1
	readFolder = 1
	moveFolder = 1
	writeFolder = 1
	renameFolder = 1
	deleteFolder = 1
	deleteSubfolders = 1

It is also possible to overwrite a permission for a specific storageObject {
	readFile = 0
	removeSubfolders = 1

Please note that these permissions only apply, if the storage has the capabilities (browseable, writable), and if the driver allows for writing etc.

Default Upload Folder for the RTE

The default upload folder for the RTE is defined by the userTSconfig of each user:

options.defaultUploadFolder = 1:/mypics/

This means that the files are put under /mypics/ of the storage with the UID 1. If none is given, it takes the first available storage and the first default folder. See the method BackendUserAuthentication->getDefaultUploadFolder() for details.

Available Drivers

See FAL_Adapters.

Open Topics / Concepts

Asset Management / DAM Replacement

see the media extension (EXT: media) for that, this is not part of FAL, however the FAL API is the basis for EXT:media.

Versioning ?

Nothing there yet, see the concept here:

MySQL Replication ?

In theory leaving out the sys_fileprocessed db table should enable MySQL Replication, but currently in 6.0.4 and 6.0.5rc1 also sys_file is breaking the replication. See


Presentation to TYPO3 6.0:

FAL Documentation:

PHP Sources: