diecoding / yii2-flysystem
The League Flysystem for local and remote filesystems library for Yii2
Fund package maintenance!
sugeng-sulistiyawan
Installs: 1 616
Dependents: 1
Suggesters: 0
Security: 0
Stars: 4
Watchers: 1
Forks: 0
Open Issues: 0
Requires
- php: >=8.0
- league/flysystem: ^3.0
- league/flysystem-path-prefixing: ^3.0
- yiisoft/yii2: ~2.0
Requires (Dev)
README
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
SiteController
for/site/file
class SiteController extends Controller { //... public function actions() { return [ // ... 'file' => [ 'class' => \diecoding\flysystem\actions\FileAction::class, // 'component' => 'fs', ], ]; } }
Remember to configure
action
key infs
application 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/