Search code examples
symfonygoogle-cloud-storagegaufrette

Example on how to config google cloud storage with KnpGaufetteBundle


I am trying to configure a KnpGaufretteBundle to use Google Cloud Storage for storing my files. This is the config:

## definition of the GCS service
app.google_cloud_storage.service:
    class: \Google_Service_Storage
    factory_class: Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory
    factory_method: 'create'
    arguments: 
        - "[email protected]"
        - "http://localhost/file.p12"
        - "pwd"

## config of knp_gaufrette
knp_gaufrette:
    stream_wrapper: ~
    adapters:
        gcs_minn_images:
            google_cloud_storage:
                service_id: 'app.google_cloud_storage.service'
                bucket_name: 'minn-images'
    filesystems:
        gcs_minn_images_fs:
            adapter: gcs_minn_images 

The error message I got is:

ContextErrorException in GoogleCloudStorageAdapterFactory.php line 16: Catchable Fatal Error: Argument 1 passed to Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory::create() must be an instance of Symfony\Component\DependencyInjection\ContainerBuilder, string given, called in /home/amine/NetBeansProjects/tuto/app/cache/dev/appDevDebugProjectContainer.php on line 724 and defined

According to the error message, I gave a string of stead of ContainerBuilder. Great! Let's add the ContainerBuilder to the arguments as follows:

## definition of the GCS service
app.google_cloud_storage.service:
    class: \Google_Service_Storage
    factory_class: Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory
    factory_method: 'create'
    arguments: 
        - @service_container
        - "[email protected]"
        - "http://localhost/file.p12"
        - "pwd"

The result is again an error:

Catchable Fatal Error: Argument 1 passed to Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory::create() must be an instance of Symfony\Component\DependencyInjection\ContainerBuilder, instance of appDevDebugProjectContainer given, called in /home/amine/NetBeansProjects/tuto/app/cache/dev/appDevDebugProjectContainer.php on line 724 and defined

So now, the error is telling me that I provide an instance of appDevDebugProjectContainer in stead of ContainerBuilder!!

Ok, let's have a look to /home/amine/NetBeansProjects/tuto/app/cache/dev/appDevDebugProjectContainer.php on line 724...

class appDevDebugProjectContainer extends Container{
// ...
/**
 * Gets the 'app.google_cloud_storage.service' service.
 *
 * This service is shared.
 * This method always returns the same instance of the service.
 *
 * @return \Google_Service_Storage A Google_Service_Storage instance.
 */
protected function getApp_GoogleCloudStorage_ServiceService()
{
    return $this->services['app.google_cloud_storage.service'] =\Knp\Bundle\GaufretteBundle\DependencyInjection\Factory\GoogleCloudStorageAdapterFactory::create($this, '[email protected]', 'http://localhost/file.p12', 'pwd');
}

I am really lost... So, is there any complete example to config google cloud storage?


Solution

  • I finally found the solution. You have to create your own factory class as described in the documentation of the bundle:

    Factory class

    <?php
    
    namespace Minn\AdsBundle\Factory;
    /**
     * Description of GoogleCloudStorageServiceFactory
     */
    class GoogleCloudStorageServiceFactory {
    
        public function createService() {
            // creating the google client
            $client = new \Google_Client();
    
            // setting the service acount credentials
            $serviceAccountName = '[email protected]';
            $scopes = array(
                'https://www.googleapis.com/auth/devstorage.read_write',
            );
            $privateKey = file_get_contents('http://localhost/f.p12');
            $privateKeyPassword = 'pwd';
    
            $credential = new \Google_Auth_AssertionCredentials(
                    $serviceAccountName, $scopes, $privateKey, $privateKeyPassword);
    
            // set assertion credentials
            $client->setAssertionCredentials($credential);
    
            // creating and returning the service
            return new \Google_Service_Storage($client);
        }
    
    }
    

    The config.yml file

    app.google_cloud_storage.service:
        class: \Google_Service_Storage
        factory: [Minn\AdsBundle\Factory\GoogleCloudStorageServiceFactory, createService]
    
    
    knp_gaufrette:
        stream_wrapper: ~
        adapters:
            gcs_images:
                google_cloud_storage:
                    service_id: 'app.google_cloud_storage.service'
                    bucket_name: 'images'
    filesystems:
        gcs_images_fs:
            adapter: gcs_images
    
    vich_uploader:
        db_driver: orm
        storage: gaufrette   
        mappings:
            motors_files:
                upload_destination: gcs_images_fs
                namer: vich_uploader.namer_origname
                delete_on_remove: true
    

    That's was it...

    Hope it will help others...