GoogleCloud Flysystem tweaks to support Uniform bucket-level access in Yii2

When Programming in PHP with the Flysystem File system, you can write files to Google Cloud using the creocoder\flysystem\GoogleCloudFilesystem

However when writing such files you can specify the Visibility and set them to public or private.
This is great, except when the bucket’s Access Control permissions is set to Uniform. In that case you can’t upload files without there being an error.

Google Cloud Bucket Access Control – Uniform

When that’s the case you’ll likely get the error:

Cannot insert legacy ACL for an object when uniform bucket-level access is enabled.
Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access

Google Cloud Upload Error

I’m using the Yii2 Framework and so set the configuration in a config/common.php file (which I then use for both the web and console files).

When trying to upload a file, by default the config looks something like this:

return [
// ...
'components' => [
'fsFileGoogle' => [
    'class' => 'creocoder\flysystem\GoogleCloudFilesystem',
    'projectId' => 'composed-yen-123456',
    'bucket' => 'example_bucket', // https://console.cloud.google.com/storage/browser/
    'keyFilePath' => '@app/config/auth/google-cloud-access.json',
],
// ...
]];

As you can see, I’m using the creocoder\flysystem\GoogleCloudFilesystem which then uses the Superbalist\Flysystem\GoogleStorage\GoogleStorageAdapter

In the Storage Adapter there’s a method called getOptionsFromConfig which forces the $options[‘predefinedAcl’] to be set.

To resolve the issue I’ve added a new VISIBILITY_NOT_SET constant and updated the setVisibility and getPredefinedAclForVisibility methods which seem to resolve the issue.
You have to use both the new GoogleCloudFilesystem.php and the GoogleStorageAdapter.php

You can now use code like below to get stuff working:

use app\adaptors\GoogleStorageAdapter;

$fs = \Yii::$app->fsFileGoogle;
$stream = fopen($fileInfo['tmp_name'], 'r+');
$writeSuccess = $fs->writeStream($filepath, $stream, ['visibility' => GoogleStorageAdapter::VISIBILITY_NOT_SET]);
// You should check the Write Success and also put all this in a try/catch, etc..

in order to write files to Google Cloud buckets with the bucket-level access set to uniform.

You’ll want to update your config so the filesystem class uses :

'class' => 'app\adaptors\GoogleCloudFilesystem',

Instead of the creocoder\flysystem\GoogleCloudFilesystem class.


I saved the files to an adaptors directory I created. e.g adaptors/GoogleCloudFilesystem.php and adaptors/GoogleStorageAdapter.php

Note that I’ve simply extended from the existing classes and overwritten what I needed. To me this is a basic form of monkey patching and I know I should be submitting a pull request, but others have a pending PR to fix the issue and some other updates that’s just been sitting there for a long time. So it looks to be an unmaintained repo.

Here’s the files:

File: adaptors/GoogleCloudFilesystem.php

File: adaptors/GoogleStorageAdapter.php

By Michael Kubler

Photographer, cinematographer, web master/coder.

Leave a comment

Your email address will not be published. Required fields are marked *