Yii2 Flysystem ¶
- Table of Contents
- Instalation
- Dependencies
- Dev. Dependencies
- Configuration
- Additional Configuration
- Usage
- Using Traits
The League Flysystem for local and remote filesystems library for Yii2.
This extension provides Flysystem 3 integration for the Yii framework. Flysystem is a filesystem abstraction which allows you to easily swap out a local filesystem for a remote one.
Yii2 Flysystem uses league/flysystem
Table of Contents ¶
- Yii2 Flysystem- Table of Contents
- Instalation
- Dependencies
- Dev. Dependencies
- Configuration
- Additional Configuration
- Usage- Writing or Updating Files
- Reading Files
- Checking if a File Exists
- Deleting Files
- Getting Files Mime Type
- Getting Files Timestamp / Last Modified
- Getting Files Size
- Creating Directories
- Checking if a Directory Exists
- Deleting Directories
- Checking if a File or Directory Exists
- Managing Visibility
- Listing contents
- Copy Files or Directories
- Move Files or Directories
- Get URL Files
- Get URL Temporary Files / Presigned URL
- Get MD5 Hash File Contents
 
- Using Traits
 
Instalation ¶
Package is available on Packagist, you can install it using Composer.
composer require diecoding/yii2-flysystem "^1.0"
or add to the require section of your composer.json file.
"diecoding/yii2-flysystem": "^1.0"
Dependencies ¶
Dev. Dependencies ¶
- league/flysystem-async-aws-s3
- league/flysystem-aws-s3-v3
- league/flysystem-google-cloud-storage
- league/flysystem-ftp
- league/flysystem-sftp-v3
- league/flysystem-webdav
- league/flysystem-ziparchive
- masbug/flysystem-google-drive-ext
Configuration ¶
Local Filesystem ¶
Configure application components as follows
return [
    // ...
    'components' => [
        // ...
        'fs' => [
            'class' => \diecoding\flysystem\LocalComponent::class,
            'path' => dirname(dirname(__DIR__)) . '/storage', // or you can use @alias
            'secret' => 'my-secret', // for secure route url
            // 'action' => '/site/file', // action route
            // 'prefix' => '',
        ],
    ],
];
AsyncAws S3 Filesystem ¶
See: league/flysystem-async-aws-s3
Either run
composer require league/flysystem-async-aws-s3:^3.0
or add
"league/flysystem-async-aws-s3": "^3.0"
to the require section of your composer.json file and configure application components as follows
return [
    // ...
    'components' => [
        // ...
        'fs' => [
            'class' => \diecoding\flysystem\AsyncAwsS3Component::class,
            'endpoint' => 'http://your-endpoint',
            'bucket' => 'my-bucket',
            'accessKeyId' => 'my-key',
            'accessKeySecret' => 'my-secret',
            // 'sharedCredentialsFile' => '~/.aws/credentials',
            // 'sharedConfigFile' => '~/.aws/config',
            // 'region' => 'us-east-1',
            // 'endpointDiscoveryEnabled' => false,
            // 'pathStyleEndpoint' => false,
            // 'sendChunkedBody' => false,
            // 'debug' => false,
            // 'prefix' => '',
        ],
    ],
];
AWS S3 Filesystem ¶
See: league/flysystem-aws-s3-v3
Either run
composer require league/flysystem-aws-s3-v3:^3.0
or add
"league/flysystem-aws-s3-v3": "^3.0"
to the require section of your composer.json file and configure application components as follows
return [
    // ...
    'components' => [
        // ...
        'fs' => [
            'class' => \diecoding\flysystem\AwsS3Component::class,
            'endpoint' => 'http://your-endpoint',
            'key' => 'your-key',
            'secret' => 'your-secret',
            'bucket' => 'your-bucket',
            // 'region' => 'us-east-1',
            // 'version' => 'latest',
            // 'usePathStyleEndpoint' => false,
            // 'streamReads' => false,
            // 'options' => [],
            // 'credentials' => [],
            // 'debug' => false,
            // 'prefix' => '',
        ],
    ],
];
Google Cloud Storage Filesystem ¶
See: league/flysystem-google-cloud-storage
Either run
composer require league/flysystem-google-cloud-storage:^3.0
or add
"league/flysystem-google-cloud-storage": "^3.0"
to the require section of your composer.json file and configure application components as follows
return [
    // ...
    'components' => [
        // ...
        'fs' => [
            'class' => \diecoding\flysystem\GoogleCloudStorageComponent::class,
            'bucket' => 'your-bucket',
            // 'apiEndpoint' => '',
            // 'projectId' => '',
            // 'authCache' => null,
            // 'authCacheOptions' => [],
            // 'authHttpHandler' => function () {},
            // 'credentialsFetcher' => null,
            // 'httpHandler' => function () {},
            // 'keyFile' => '',
            'keyFilePath' => __DIR__ . '/gcs_credentials.json',
            // 'requestTimeout' => 0,
            // 'retries' => 0,
            // 'scopes' => [],
            // 'quotaProject' => '',
            // 'userProject' => false,
            // 'prefix' => '',
        ],
    ],
];
FTP Filesystem ¶
See: league/flysystem-ftp
Either run
composer require league/flysystem-ftp:^3.0
or add
"league/flysystem-ftp": "^3.0"
to the require section of your composer.json file and configure application components as follows
return [
    // ...
    'components' => [
        // ...
        'fs' => [
            'class' => \diecoding\flysystem\FtpComponent::class,
            'host' => 'hostname',
            'root' => '/root/path/', // or you can use @alias
            'username' => 'username',
            'password' => 'password',
            // 'port' => 21,
            // 'ssl' => false,
            // 'timeout' => 90,
            // 'utf8' => false,
            // 'passive' => true,
            // 'transferMode' => FTP_BINARY,
            // 'systemType' => null, // 'windows' or 'unix'
            // 'ignorePassiveAddress' => null, // true or false
            // 'timestampsOnUnixListingsEnabled' => false,
            // 'recurseManually' => true,
            // 'useRawListOptions' => null, // true or false
            // 'passphrase' => 'secret', // for secure route url
            // 'action' => '/site/file', // action route
            // 'prefix' => '',
        ],
    ],
];
SFTP Filesystem ¶
Either run
composer require league/flysystem-sftp-v3:^3.0
or add
"league/flysystem-sftp-v3": "^3.0"
to the require section of your composer.json file and configure application components as follows
return [
    // ...
    'components' => [
        'fs' => [
            'class' => \diecoding\flysystem\SftpComponent::class,
            'host' => 'hostname',
            'username' => 'username',
            'password' => null, // password (optional, default: null) set to null if privateKey is used
            // 'privateKey' => '/path/to/my/private_key', // private key (optional, default: null) can be used instead of password, set to null if password is set
            // 'passphrase' => 'super-secret-password', // passphrase (optional, default: null), set to null if privateKey is not used or has no passphrase
            // 'port' => 22,
            // 'useAgent' => true,
            // 'timeout' => 10,
            // 'maxTries' => 4,
            // 'hostFingerprint' => null,
            // 'connectivityChecker' => null, // connectivity checker (must be an implementation of `League\Flysystem\PhpseclibV2\ConnectivityChecker` to check if a connection can be established (optional, omit if you don't need some special handling for setting reliable connections)
            // 'preferredAlgorithms' => [],
            // 'root' => '/root/path/', // or you can use @alias
            // 'action' => '/site/file', // action route
            // 'prefix' => '',
        ],
    ],
];
WebDAV Filesystem ¶
Either run
composer require league/flysystem-webdav:^3.0
or add
"league/flysystem-webdav": "^3.0"
to the require section of your composer.json file and configure application components as follows
return [
    // ...
    'components' => [
        // ...
        'fs' => [
            'class' => \diecoding\flysystem\WebDavComponent::class,
            'baseUri' => 'http://your-webdav-server.org/',
            'userName' => 'your_user',
            'password' => 'superSecret1234',
            // 'proxy' => '',
            // 'authType' => \Sabre\DAV\Client::AUTH_BASIC,
            // 'encoding' => \Sabre\DAV\Client::ENCODING_IDENTITY,
            // 'prefix' => '',
        ],
    ],
];
ZipArchive Filesystem ¶
See: league/flysystem-ziparchive
Either run
composer require league/flysystem-ziparchive:^3.0
or add
"league/flysystem-ziparchive": "^3.0"
to the require section of your composer.json file and configure application components as follows
return [
    // ...
    'components' => [
        // ...
        'fs' => [
            'class' => \diecoding\flysystem\ZipArchiveComponent::class,
            'pathToZip' => dirname(dirname(__DIR__)) . '/storage.zip', // or you can use @alias
            'secret' => 'my-secret', // for secure route url
            // 'action' => '/site/file', // action route
            // 'prefix' => '', // root directory inside zip file
        ],
    ],
];
Google Drive Filesystem ¶
See: masbug/flysystem-google-drive-ext
Either run
composer require masbug/flysystem-google-drive-ext:^2.0
or add
"masbug/flysystem-google-drive-ext": "^2.0"
to the require section of your composer.json file and configure application components as follows
return [
    // ...
    'components' => [
        // ...
        'fs' => [
            'class' => \diecoding\flysystem\GoogleDriveComponent::class,
            'applicationName' => 'My Google Drive App',
            'clientId' => '',
            'clientSecret' => '',
            'refreshToken' => '',
            // 'teamDriveId' => '',
            // 'sharedFolderId' => '',
            // 'options' => [],
            'secret' => 'my-secret', // for secure route url
            // 'action' => '/site/file', // action route
            // 'prefix' => '',
        ],
    ],
];
Additional Configuration ¶
URL File Action Settings ¶
The following adapters have URL File Action generation capabilities:
- Local Component
- FTP Component
- SFTP Component
- Google Drive Component
Configure action in controller as follows
This example at
SiteControllerfor/site/file
class SiteController extends Controller
{
    //...
    public function actions()
    {
        return [
            // ...
            'file' => [
                'class' => \diecoding\flysystem\actions\FileAction::class,
                // 'component' => 'fs',
            ],
        ];
    }
}
Remember to configure
actionkey infsapplication components as follows
return [
    // ...
    'components' => [
        // ...
        'fs' => [
            // ...
            'action' => '/site/file', // action for get url file
        ],
    ],
];
Global Visibility Settings ¶
Configure fs application component as follows
return [
    //...
    'components' => [
        //...
        'fs' => [
            //...
            'config' => [
                'visibility' => \League\Flysystem\Visibility::PRIVATE,
            ],
        ],
    ],
];
Usage ¶
Writing or Updating Files ¶
To write or update file
Yii::$app->fs->write('filename.ext', 'contents');
To write or update file using stream contents
$stream = fopen('/path/to/somefile.ext', 'r+');
Yii::$app->fs->writeStream('filename.ext', $stream);
Reading Files ¶
To read file
$contents = Yii::$app->fs->read('filename.ext');
To retrieve a read-stream
$stream = Yii::$app->fs->readStream('filename.ext');
$contents = stream_get_contents($stream);
fclose($stream);
Checking if a File Exists ¶
To check if a file exists
$exists = Yii::$app->fs->fileExists('filename.ext');
Deleting Files ¶
To delete file
Yii::$app->fs->delete('filename.ext');
Getting Files Mime Type ¶
To get file mime type
$mimeType = Yii::$app->fs->mimeType('filename.ext');
Getting Files Timestamp / Last Modified ¶
To get file timestamp
$timestamp = Yii::$app->fs->lastModified('filename.ext');
Getting Files Size ¶
To get file size
$byte = Yii::$app->fs->fileSize('filename.ext');
Creating Directories ¶
To create directory
Yii::$app->fs->createDirectory('path/to/directory');
Directories are also made implicitly when writing to a deeper path
Yii::$app->fs->write('path/to/filename.ext');
Checking if a Directory Exists ¶
To check if a directory exists
$exists = Yii::$app->fs->directoryExists('path/to/directory');
Deleting Directories ¶
To delete directory
Yii::$app->fs->deleteDirectory('path/to/directory');
Checking if a File or Directory Exists ¶
To check if a file or directory exists
$exists = Yii::$app->fs->has('path/to/directory/filename.ext');
Managing Visibility ¶
Visibility is the abstraction of file permissions across multiple platforms. Visibility can be either public or private.
Yii::$app->fs->write('filename.ext', 'contents', [
    'visibility' => \League\Flysystem\Visibility::PRIVATE
]);
You can also change and check visibility of existing files
if (Yii::$app->fs->visibility('filename.ext') === \League\Flysystem\Visibility::PRIVATE) {
    Yii::$app->fs->setVisibility('filename.ext', \League\Flysystem\Visibility::PUBLIC);
}
Listing contents ¶
To list contents
$contents = Yii::$app->fs->listContents();
foreach ($contents as $object) {
    echo $object['basename']
        . ' is located at' . $object['path']
        . ' and is a ' . $object['type'];
}
By default Flysystem lists the top directory non-recursively. You can supply a directory name and recursive boolean to get more precise results
$contents = Yii::$app->fs->listContents('path/to/directory', true);
Copy Files or Directories ¶
To copy contents
Yii::$app->fs->copy('path/from/directory/filename.ext', 'path/to/directory/filename.ext', [
    'visibility' => \League\Flysystem\Visibility::PRIVATE
]);
Move Files or Directories ¶
To move contents
Yii::$app->fs->move('path/from/directory/filename.ext', 'path/to/directory/filename.ext', [
    'visibility' => \League\Flysystem\Visibility::PRIVATE
]);
Get URL Files ¶
To get url contents
Yii::$app->fs->publicUrl('path/to/directory/filename.ext');
Get URL Temporary Files / Presigned URL ¶
To get temporary url contents
$expiresAt = new \DateTimeImmutable('+10 Minutes');
Yii::$app->fs->temporaryUrl('path/to/directory/filename.ext', $expiresAt);
The $expiresAt should be a valid and instance of PHP DateTimeInterface. Read PHP documentation for details.
Get MD5 Hash File Contents ¶
To get MD5 hash of the file contents
Yii::$app->fs->checksum('path/to/directory/filename.ext');
Using Traits ¶
Model Trait ¶
Attach the Trait to the Model/ActiveRecord with some media attribute that will be saved in Flysystem (fs):
/**
 * @property string|null $file
 */
class Model extends \yii\db\ActiveRecord
{
    use \diecoding\flysystem\traits\ModelTrait;
    // ...
    public function rules()
    {
        return [
            ['image', 'string'], // Stores the filename
        ];
    }
    /**
     * @inheritdoc
     */
    protected function attributePaths()
    {
        return [
            'image' => 'images/'
        ];
    }
    // ...
}
Override the attributePaths() method to change the base path where the files will be saved on Flysystem (fs).
- You can map a different path to each file attribute of your Model/ActiveRecord.
Using Trait Methods ¶
$image = \yii\web\UploadedFile::getInstance($model, 'image');
// Save image_thumb.* to Flysystem (fs) on //my_bucket/images/ path
// The extension of the file will be determined by the submitted file type
// This allows multiple file types upload (png,jpg,gif,...)
// $model->image will hold "image_thumb.png" after this call finish with success
$model->saveUploadedFile($image, 'image', 'image_thumb');
$model->save();
// Save image_thumb.png to Flysystem (fs) on //my_bucket/images/ path
// The extension of the file will be determined by the submitted file type
// This force the extension to *.png
$model->saveUploadedFile($image, 'image', 'image_thumb.png', false);
$model->save();
// Remove the file with named saved on the image attribute
// Continuing the example, here "//my_bucket/images/my_image.png" will be deleted from Flysystem (fs)
$model->removeFile('image');
$model->save();
// Get the URL to the image on Flysystem (fs)
$model->getFileUrl('image');
// Get the presigned URL to the image on Flysystem (fs)
// The default duration is "+5 Minutes"
$model->getFilePresignedUrl('image');
Overriding Trait Methods ¶
getFsComponent ¶
The Flysystem (fs) MediaTrait depends on this component to be configured. The default configuration is to use this component on index 'fs', but you may use another value. For this cases, override the getFsComponent() method:
public function getFsComponent()
{
    return Yii::$app->get('my_fs_component');
}
attributePaths ¶
The main method to override is attributePaths(), which defines a path in Flysystem (fs) for each attribute of yout model. Allowing you to save each attribute in a different Flysystem (fs) folder.
Here an example:
protected function attributePaths()
{
    return [
        'logo' => 'logos/',
        'badge' => 'images/badges/'
    ];
}
// or use another attribute, example: id
// ! Note: id must contain a value first if you don't want it to be empty
protected function attributePaths()
{
    return [
        'logo' => 'thumbnail/' . $this->id . '/logos/',
        'badge' => 'thumbnail/' . $this->id . '/images/badges/'
    ];
}
getPresignedUrlDuration ¶
The default pressigned URL duration is set to "+5 Minutes", override this method and use your own expiration.
Return must instance of DateTimeInterface
protected function getPresignedUrlDuration($attribute)
{
    return new \DateTimeImmutable('+2 Hours');
}
// or if you want to set the attribute differently
protected function getPresignedUrlDuration($attribute)
{
    switch ($attribute) {
        case 'badge':
            return new \DateTimeImmutable('+2 Hours');
            break;
        
        default:
            return new \DateTimeImmutable('+1 Days');
            break;
    }
}
The value should be a valid and instance of PHP DateTimeInterface. Read PHP documentation for details.
Read more docs: https://sugengsulistiyawan.my.id/docs/opensource/yii2/flysystem/
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.