mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-09-18 23:46:21 +02:00
185 lines
7.4 KiB
Markdown
185 lines
7.4 KiB
Markdown
title: File storage
|
|
summary: Describes the persistence layer of files
|
|
|
|
# File storage
|
|
|
|
This section describes how the asset store abstraction layer stores the physical files underlying the ORM,
|
|
and explains some of the considerations.
|
|
|
|
## Component Overview
|
|
|
|
The assets module is composed of these major storage classes:
|
|
|
|
* [api:SilverStripe\Assets\File]: This is the main DataObject that user code interacts with when working with files.
|
|
This class has the following subclasses:
|
|
- [api:SilverStripe\Assets\Folder]: Logical folder which holds a set of files. These can be nested.
|
|
- [api:SilverStripe\Assets\Image]: Specialisation of File representing an image which can be resized.
|
|
Note that this does not include non-resizable image files.
|
|
* [api:SilverStripe\Assets\Storage\DBFile]: This is the DB field used by the File dataobject internally for
|
|
storing references to physical files in the asset backend.
|
|
* [api:SilverStripe\Assets\Flysystem\FlysystemAssetStore]: The default backend, provided by
|
|
[Flysystem](https://flysystem.thephpleague.com/), which SilverStripe uses as an asset persistence layer.
|
|
* [api:SilverStripe\Assets\InterventionBackend]: Default image resizing mechanism, provided by
|
|
[intervention image](http://image.intervention.io/).
|
|
|
|
These interfaces are also provided to abstract certain behaviour:
|
|
|
|
* [api:SilverStripe\Assets\Storage\AssetContainer]: Abstract interface for a file reference. Implemented by both
|
|
File and DBFile. Declare API for reading to and writing an single file.
|
|
* [api:SilverStripe\Assets\Storage\AssetStore]: Abstract interface for the backend store for the asset system.
|
|
Implemented by FlysystemAssetStore. Declares API for reading and writing assets from and to the store.
|
|
|
|
## Storage via database columns
|
|
|
|
Asset storage is provided out of the box via a [Flysystem](http://flysystem.thephpleague.com/) backed store.
|
|
However, any class that implements the `AssetStore` interface could be substituted to provide storage backends
|
|
via other mechanisms.
|
|
|
|
Internally, files are stored as [DBFile](api:SilverStripe\Assets\Storage\DBFile) records on the rows of parent objects.
|
|
These records are composite fields which contain sufficient information useful to the configured asset backend in order
|
|
to store, manage, and publish files. By default this composite field behind this field stores the following details:
|
|
|
|
|
|
| Field name | Description |
|
|
| ---------- | -----------
|
|
| `Hash` | The sha1 of the file content, useful for versioning (if supported by the backend) |
|
|
| `Filename` | The internal identifier for this file, which may contain a directory path (not including assets). Multiple versions of the same file will have the same filename. |
|
|
| `Variant` | The variant for this file. If a file has multiple derived versions (such as resized files or reformatted documents) then you can point to one of the variants here. |
|
|
|
|
|
|
Note that the `Hash` and `Filename` always point to the original file, if a `Variant` is specified. It is up to the
|
|
storage backend to determine how variants are managed.
|
|
|
|
Note that the storage backend used will not be automatically synchronised with the database. Only files which
|
|
are loaded into the backend through the asset API will be available for use within a site.
|
|
|
|
## Public file paths
|
|
|
|
Public files are published either directly through the "Assets" CMS UI,
|
|
or indirectly as part of a [versioned ownership structure](/developer_guides/model/versioning).
|
|
They are stored as you'd expect on the filesystem: In their folder, by their file name.
|
|
|
|
```
|
|
assets/
|
|
my-public-folder/
|
|
my-public-file.jpg
|
|
```
|
|
|
|
The URL for this file will match the physical location on disk:
|
|
`http://www.example.com/assets/my-public-folder/my-public-file.jpg`.
|
|
|
|
## Variant file paths (e.g. resized images) {#variant-file-paths}
|
|
|
|
Each file can have variants, most commonly resized versions of an image.
|
|
These can be generated by resizing an image in the CMS rich text editor,
|
|
through template logic, or programmatically with PHP.
|
|
They are stored in the same folder alongside the original file,
|
|
but contain a special variant suffix.
|
|
|
|
```
|
|
assets/
|
|
my-public-folder/
|
|
my-public-file.jpg
|
|
my-public-file__FitWzYwLDYwXQ.jpg
|
|
```
|
|
|
|
The URL for this file will match the physical location on disk:
|
|
`http://www.example.com/assets/my-public-folder/my-public-file__FitWzYwLDYwXQ.jpg`.
|
|
|
|
Note: Before 4.4.0, public files were stored with a content hash by default
|
|
(see [Protected file paths](#protected-file-paths)).
|
|
|
|
## Protected file paths {#protected-file-paths}
|
|
|
|
Uploaded files are protected by default, which puts them in a "draft" mode
|
|
that requires permissions to view them. Protected files can also be published
|
|
but access restricted. In either case, they're stored in a special `assets/.protected` folder.
|
|
In this case, they're stored in a folder matching the truncated hash of the file's content.
|
|
|
|
```
|
|
assets/
|
|
my-public-folder/
|
|
my-public-file.jpg
|
|
my-public-file__FitWzYwLDYwXQ.jpg
|
|
.protected/
|
|
my-protected-folder/
|
|
b63923d8d4/
|
|
my-protected-file.jpg
|
|
my-protected-file__FitWzYwLDYwXQ.jpg
|
|
```
|
|
|
|
This corresponds to a file with the following properties:
|
|
|
|
- Filename: my-protected-folder/my-protected-file-hash/my-protected-file.jpg
|
|
- Hash: b63923d8d4089c9da16fbcbcdfef3e1b24806334 (trimmed to first 10 chars)
|
|
- Variant: FitWzYwLDYwXQ (corresponds to `Fit[60,60]`)
|
|
|
|
The URL for this file will not match the physical location on disk.
|
|
It leaves out the `.protected/` folder, and leaves that to SilverStripe's integrated routing:
|
|
`http://www.example.com/assets/my-protected-folder/b63923d8d4/my-protected-file.jpg`.
|
|
|
|
For more information on how protected files are stored see the [file security](/developer_guides/files/file_security)
|
|
section.
|
|
|
|
## Versioned file paths
|
|
|
|
Older versions of file contents are kept in the `.protected` folder,
|
|
following the same rules as [protected file paths](#protected-file-paths).
|
|
|
|
```
|
|
assets/
|
|
my-file.jpg <- current published file
|
|
.protected/
|
|
dec83f348d/ <- old content hash of replaced file version
|
|
my-file.jpg
|
|
b63923d8d4/ <- old content hash of replaced file version
|
|
my-file.jpg
|
|
```
|
|
|
|
## Versioned and archived files {#archived}
|
|
|
|
By default, when files are replaced or removed, their original file contents
|
|
aren't retained in order to avoid bloat on the filesystem.
|
|
Changes are only tracked for file metadata (e.g. the `Title` attribute).
|
|
|
|
You can opt-in to retaining the file content for replaced or removed files.
|
|
|
|
```yml
|
|
SilverStripe\Assets\Flysystem\FlysystemAssetStore:
|
|
keep_archived_assets: true
|
|
```
|
|
|
|
The filesystem structure follows the same rules as [protected file paths](#protected-file-paths):
|
|
|
|
```
|
|
assets/
|
|
my-file.jpg <- current published file
|
|
.protected/
|
|
dec83f348d/ <- old content hash of replaced file version
|
|
my-file.jpg
|
|
b63923d8d4/ <- old content hash of replaced file version
|
|
my-file.jpg
|
|
```
|
|
|
|
## Loading content into `DBFile`
|
|
|
|
A file can be written to the backend from a file which exists on the local filesystem (but not necessarily
|
|
within the assets folder).
|
|
|
|
For example, to load a temporary file into a DataObject you could use the below:
|
|
|
|
```php
|
|
use SilverStripe\ORM\DataObject;
|
|
|
|
class Banner extends DataObject
|
|
{
|
|
private static $db = [
|
|
'Image' => 'DBFile'
|
|
];
|
|
}
|
|
|
|
// Image could be assigned in other parts of the code using the below
|
|
$banner = new Banner();
|
|
$banner->Image->setFromLocalFile($tempfile['path'], 'my-folder/my-file.jpg');
|
|
```
|