# media-cloud-sync/1.2.2/includes/base/services/gcloud.php

Media Cloud Sync, version 1.2.2. 671 lines.

- Page: https://pluginprobe.com/plugins/media-cloud-sync/1.2.2/code/includes/base/services/gcloud.php
- Raw: https://pluginprobe.com/plugins/media-cloud-sync/1.2.2/raw/includes/base/services/gcloud.php
- Modified: 2025-06-02T11:27:00+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/media-cloud-sync/1.2.2/code/includes/base/services/gcloud.php#L10-L20`.

```php
<?php
namespace Dudlewebs\WPMCS;

defined('ABSPATH') || exit;

// Libraries
use Dudlewebs\WPMCS\Google\Cloud\Storage\StorageClient;
use Dudlewebs\WPMCS\Google\Cloud\Core\Exception\ServiceException;

use Exception;

class GCloud {
    private $assets_url;
    private $version;
    private $token;

    protected $config;
    protected $bucketConfig;
    protected $settings;
    protected $credentials;
    protected $bucket_name;
    protected $bucket; // Object

    public $service         = 'gcloud';
    public $gcloudClient    = false;

    /**
     * Admin constructor.
     * @since 1.0.0
     */
    public function __construct() {
        $this->assets_url = WPMCS_ASSETS_URL;
        $this->version    = WPMCS_VERSION;
        $this->token      = WPMCS_TOKEN;

        // Initialize setup
        $this->init();
    }

    /**
     * Initialise Client
     */
    public function init() {
        $this->settings     = Utils::get_settings();
        $this->credentials  = Utils::get_credentials();
        $this->config       = isset($this->credentials['config']) && !empty($this->credentials['config']) 
                                ? $this->credentials['config']
                                : [];
        $this->bucketConfig =  isset($this->credentials['bucketConfig']) && !empty($this->credentials['bucketConfig']) 
                                ? $this->credentials['bucketConfig']
                                : [];
        $this->bucket_name  =  isset($this->bucketConfig['bucket_name']) && !empty($this->bucketConfig['bucket_name']) 
                                ? $this->bucketConfig['bucket_name']
                                : '';

        if (
            isset($this->config['config_json']) && !empty($this->config['config_json']) &&
            isset($this->config['config_json']['path']) && !empty($this->config['config_json']['path']) &&
            isset($this->bucket_name) && !empty($this->bucket_name)
        ) {
            if(file_exists($this->config['config_json']['path'])){
                // Set google client
                $this->gcloudClient = new StorageClient([
                    'keyFilePath' => $this->config['config_json']['path'],
                ]);
                // Set bucket object
                $this->bucket = $this->gcloudClient->bucket($this->bucket_name);
            } else {
                add_action('admin_notices', function (){
                    echo wp_kses_post(sprintf( "<div class='error'><p><strong>%s: </strong><br>Google Cloud Storage configuration file missing from the directory.
                                        It may break the media url's as well as media uploads.<br>
                                        <a href='%s'>Re-configure</a> plugin to fix the issue.
                                        </p></div>", 
                                        esc_html__('Media Cloud Sync', 'media-cloud-sync'),
                                        admin_url('admin.php?page='.$this->token . '-admin-ui#/configure')
                                    ));
                });
            }       
        }
    }

    /**
     * Verify Credentials
     * @since 1.0.0
     * @return boolean
     */
    public function verifyCredentials( $config_file ){
        if (
            isset($config_file) && !empty($config_file) &&
            isset($config_file['path']) && !empty($config_file['path']) &&
            file_exists($config_file['path'])
        ) {
            try {
                $googleClient = new StorageClient([
                    'keyFilePath' => $config_file['path'],
                ]);

                $result = [
                    'success' => false,
                    'code'    => 200,
                    'message' => esc_html__('Please check the authorization details', 'media-cloud-sync'),
                ];

                try {
                    $bucket = $googleClient->bucket($this->token . '_dummy-bucket-for-auth-check');
                    $exists = $bucket->exists(); // Triggers the API call

                    // If we reach here, the credentials are valid
                    $result = [
                        'success' => true,
                        'code'    => 200,
                        'message' => esc_html__('Credentials are valid', 'media-cloud-sync'),
                    ];
                } catch (ServiceException $e) {
                    $statusCode = $e->getCode();
            
                    $validErrors = [200, 403, 404];
            
                    if (in_array($statusCode, $validErrors)) {
                        // If we reach here, the credentials are valid
                        $result = [
                            'success' => true,
                            'code'    => 200,
                            'message' => esc_html__('Credentials are valid', 'media-cloud-sync'),
                        ];
                    }
                }

                if($result['success'] == false) {
                    return $result;
                }


                try {
                    $buckets = $googleClient->buckets();
                    $newBucketFormat = [];
                    if(isset($buckets) && !empty($buckets)){
                        foreach($buckets as $bucket) {
                            $name = $bucket->name();
                            if(!empty($name)) {
                                // Fetch the bucket's metadata
                                $bucketInfo = $bucket->info();
                                $newBucketFormat[] = ['Name' => $name, 'CreationDate' => $bucketInfo['timeCreated']];
                            }
                        }
                    }
                    $result['buckets_data']['buckets'] = $newBucketFormat;
                    $result['buckets_data']['message'] = esc_html__('Buckets listed successfully', 'media-cloud-sync');
                    $result['buckets_data']['status'] = true;
                } catch (Exception $e) {
                    $result ['buckets_data']['buckets'] = [];
                    $result ['buckets_data']['message'] = esc_html__('Unable to list buckets, Please check the bucket listing permission', 'media-cloud-sync');
                    $result ['buckets_data']['status'] = false;
                }
                return $result;
            } catch (Exception $ex) {
                return array('message' => $ex->getMessage() ?? esc_html__('Please check the authorization details', 'media-cloud-sync'), 'code' => 200, 'success' => false);
            }
        }
        return array('message' => esc_html__('Insufficient Data. Please try again', 'media-cloud-sync'), 'code' => 200, 'success' => false);
    }


    /**
     * Verify Bucket Exists
     * @since 1.0.0
     * @return boolean
     */
    public function verifyBucketExist( $config_file, $bucket_name ){
        if ( !( isset($config_file['path']) && !empty($config_file['path']) && file_exists($config_file['path']) && !empty($bucket_name) ) ) {
            return ['message' => esc_html__('Insufficient Data. Please try again', 'media-cloud-sync'), 'code' => 200, 'success' => false];
        }

        try {
            $googleClient = new StorageClient([
                'keyFilePath' => $config_file['path'],
            ]);

            try {
                $bucket = $googleClient->bucket($bucket_name);

                // Try fetching a dummy object to test access, like you did with S3
                $object = $bucket->object($this->token . '_dummy-object-for-bucket-exist-check');
                $object->info(); // Will throw if bucket doesn't exist or access is denied

                return [
                    'message' => esc_html__('Bucket exists', 'media-cloud-sync'),
                    'code'    => 200,
                    'success' => true,
                ];
            } catch (ServiceException $e) {
                $code = $e->getCode();

                if (in_array($code, [403, 404], true)) {
                    return [
                        'message' => esc_html__('Bucket exists', 'media-cloud-sync'),
                        'code'    => 200,
                        'success' => true,
                    ];
                }

                return [
                    'message' => esc_html__('Bucket does not exist or credentials are invalid: ', 'media-cloud-sync') . $e->getMessage(),
                    'code'    => 200,
                    'success' => false,
                ];
            }
            

            if($bucket_found) {
                    return array('message' => esc_html__('Bucket exist', 'media-cloud-sync'), 'code' => 200, 'success' => true);
            } else {
                return array('message' => esc_html__("Bucket choosen does not exist / does not have read permission", 'media-cloud-sync'), 'code' => 200, 'success' => false);
            }
        } catch (Exception $ex) {
            return ['message' => $ex->getMessage() ?? esc_html__('Please check the authorization details', 'media-cloud-sync'), 'code' => 200, 'success' => false];
        }
    }


    /**
     * Create Bucket
     * @since 1.0.0
     * @return boolean
     */
    public function createBucket( $config_file, $region, $bucket_name ){
        if ( !( isset($config_file['path']) && !empty($config_file['path']) && file_exists($config_file['path']) && !empty($region) && !empty($bucket_name) ) ) {
            return ['message' => esc_html__('Insufficient Data. Please try again', 'media-cloud-sync'), 'code' => 200, 'success' => false];
        }

        try {
            $googleClient = new StorageClient([
                'keyFilePath' => $config_file['path'],
            ]);

            // Create Bucket
            $googleClient->createBucket($bucket_name, [
                'location' => $region,
            ]);

            return [
                'message' => esc_html__('Bucket created successfully. Choose bucket from list to select the bucket.', 'media-cloud-sync'),
                'data'    => [
                    'Name'         => $bucket_name,
                    'CreationDate' => date('Y-m-d\TH:i:s\Z'),
                ],
                'code'    => 200,
                'success' => true,
            ];
               
        } catch (Exception $ex) {
            return ['message' => $e->getMessage() ?? esc_html__('Please check the authorization details', 'media-cloud-sync'), 'code' => 200, 'success' => false];
        }
    }

    /**
     * Check Bucket Write Permission
     * @since 1.0.0
     */ 
    public function verifyObjectWritePermission($config_file, $bucket_name){
        if ( !( isset($config_file['path']) && !empty($config_file['path']) && file_exists($config_file['path']) && !empty($bucket_name) ) ) {
            return ['message' => esc_html__('Insufficient Data. Please try again', 'media-cloud-sync'), 'code' => 200, 'success' => false];
        }

        try {
            $googleClient = new StorageClient([
                'keyFilePath' => $config_file['path'],
            ]);

            $bucket = $googleClient->bucket($bucket_name);
            if ($bucket->exists()) {
                $bucket_found = true;
            } else {
                return ['message' => esc_html__('No Buckets found', 'media-cloud-sync'), 'code' => 200, 'success' => false];
            }
            if ($bucket_found) {
                $object_key = Utils::generate_object_key($this->token . '_dummy-object-for-bucket-permission-check', '');

                // Prepare a temporary file with content to check write permission
                $stream = fopen('php://temp', 'r+');
                fwrite($stream, 'This is a test object to check write permission.');
                rewind($stream);

                // Upload the object to the bucket
                $object = $bucket->upload(
                    $stream,
                    [
                        'name' => $object_key,
                    ]
                );
                if(is_resource($stream)) {
                    fclose($stream);
                }                

                if ($object->exists()) {
                    return ['message' => esc_html__('Bucket write permission verified successfully', 'media-cloud-sync'), 'code' => 200, 'success' => true]; 
                } else {
                    return ['message' => esc_html__('Bucket write permission not verified', 'media-cloud-sync'), 'code' => 200, 'success' => false];
                }
            }
        } catch (Exception $ex) {
            return ['message' => $ex->getMessage() ?? esc_html__('Please check the authorization details', 'media-cloud-sync'), 'code' => 200, 'success' => false];
        }
    }

    /**
     * Check Bucket Delete Permission
     * @since 1.0.0
     */ 
    public function verifyObjectDeletePermission($config_file, $bucket_name){
        if ( !( isset($config_file['path']) && !empty($config_file['path']) && file_exists($config_file['path']) && !empty($bucket_name) ) ) {
            return ['message' => esc_html__('Insufficient Data. Please try again', 'media-cloud-sync'), 'code' => 200, 'success' => false];
        }

        try {
            $googleClient = new StorageClient([
                'keyFilePath' => $config_file['path'],
            ]);

            $bucket = $googleClient->bucket($bucket_name);
            try {
                $object_key = Utils::generate_object_key($this->token . '_dummy-object-for-bucket-permission-check', '');
                
                // Try fetching a dummy object to test access, like you did with S3
                $object = $bucket->object($object_key);
                if ($object->exists()) {
                    $object->delete();  
                    if (!$object->exists()) {
                        return [
                            'message' => esc_html__('Bucket exists', 'media-cloud-sync'),
                            'code'    => 200,
                            'success' => true,
                        ];
                    } else {
                        return [
                            'message' => esc_html__('You do not have permission to delete object', 'media-cloud-sync'),
                            'code'    => 200,
                            'success' => false,
                        ];
                    }
                } else {
                    return [
                        'message' => esc_html__('Object does not exist', 'media-cloud-sync'),
                        'code'    => 200,
                        'success' => false,
                    ];
                }
            } catch (Exception $ex) {
                return [
                    'message' => esc_html__('Object does not exist or credentials are invalid: ', 'media-cloud-sync') . $e->getMessage(),
                    'code'    => 200,
                    'success' => false,
                ];
            }
           
        } catch (Exception $ex) {
            return ['message' => $ex->getMessage() ?? esc_html__('Please check the authorization details', 'media-cloud-sync'), 'code' => 200, 'success' => false];
        }
    }

    /**
     * isConfigured Function To Identify the congfigurations are correct
     * @since 1.0.0
     */
    public function isConfigured(){
        if ($this->gcloudClient) {
            try {
                $buckets = $this->gcloudClient->buckets();
                if(!empty($buckets)){
                    foreach($buckets as $bucket) {
                        $name = $bucket->name();
                        if (!empty($name) && $name == $this->bucket_name) {
                            return true;
                        }
                    }
                } 
                return false;
            } catch (Exception $ex) {
                return false;
            }
        }
        return false;
    }

    /**
     * Make Object Private
     * @since 1.0.0
     * 
     */
    public function toPrivate($key) {
        if(!$key) return false;

        $object = $this->bucket->object($key);
        if ($object->exists()) {
            $object->update(['acl' => []], ['predefinedAcl' => 'private']);
            return true;
        }
        return false;
    }


    /**
     * Make Object Public
     * @since 1.0.0
     * 
     */
    public function toPublic($key) {
        if(!$key) return false;

        $object = $this->bucket->object($key);
        if ($object->exists()) {
            $object->update(['acl' => []], ['predefinedAcl' => 'publicRead']);
            return true;
        }
        return false;
    }


    /**
     * Check the object exist 
     * @since 1.1.8
     */
    public function exists($key) {
        if(!$key) return false;
        
        $object = $this->bucket->object($key);
        if ($object->exists()) {
            return true;
        }
        
        return false;
    }


    /**
     * Upload Single
     * @since 1.0.0
     * @return boolean
     */
    public function uploadSingle($media_absolute_path, $media_path, $prefix=''){
        $result = array();
        if (
            isset($media_absolute_path) && !empty($media_absolute_path) &&
            isset($media_path) && !empty($media_path)
        ) {
            $file_name = wp_basename( $media_path );
            if ($file_name) {
                $upload_path = Utils::generate_object_key($media_path, $prefix);

                // Decide Multipart upload or normal put object
                if (filesize($media_absolute_path) <= Schema::getConstant('GCLOUD_MULTIPART_MIN_FILE_SIZE')) {
                    // Upload a publicly accessible file. The file size and type are determined by the SDK.
                    try {

                        $upload = $this->bucket->upload(
                            fopen($media_absolute_path, 'r'),
                            [
                                'name' => $upload_path,
                            ]
                        );

                        $object = $this->bucket->object($upload_path);

                        if ($object->exists()) {
                            $result = array(
                                'success'   => true,
                                'code'      => 200,
                                'file_url'  => $this->generate_file_url($upload_path),
                                'key'       => $upload_path,
                                'message'   => esc_html__('File Uploaded Successfully', 'media-cloud-sync'),
                            );
                        } else {
                            $result = array(
                                'success'   => false,
                                'code'      => 200,
                                'message'   => esc_html__('Object not found at server.', 'media-cloud-sync'),
                            );
                        }
                    } catch (Exception $e) {
                        $result = array(
                            'success' => false,
                            'code' => 200,
                            'message' => $e->getMessage(),
                        );
                    }
                } else {
                    try {
                        $upload = $this->bucket->upload(
                            fopen($media_absolute_path, 'r'),
                            [
                                'name' => $upload_path,
                                'chunkSize' => 262144 * 2,
                            ]
                        );

                        $object = $this->bucket->object($upload_path);

                        if ($object->exists()) {
                            $result = array(
                                'success' => true,
                                'code' => 200,
                                'file_url' => $this->generate_file_url($upload_path),
                                'key' => $upload_path,
                                'message' => esc_html__('File Uploaded Successfully', 'media-cloud-sync'),
                            );
                        } else {
                            $result = array(
                                'success'   => false,
                                'code'      => 200,
                                'message'   => esc_html__('Something happened while uploading to server', 'media-cloud-sync'),
                            );
                        }
                    } catch (Exception $e) {
                        $result = array(
                            'success'   => false,
                            'code'      => 200,
                            'message'   => $e->getMessage(),
                        );
                    }
                }
            } else {
                $result = array(
                    'success'   => false,
                    'code'      => 200,
                    'message'   => esc_html__('Check the file you are trying to upload. Please try again', 'media-cloud-sync'),
                );
            }
        } else {
            $result = array(
                'success'   => false,
                'code'      => 200,
                'message'   => esc_html__('Insufficient Data. Please try again', 'media-cloud-sync'),
            );
        }
        return $result;
    }


    /**
     * Save object to server
     * @since 1.0.0
     */
    public function object_to_server($key, $save_path){
        try {
            $object = $this->bucket->object($key);
            if ($object->exists()) {
                $object->downloadToFile($save_path);
                if (file_exists($save_path)) {
                    return true;
                }
            }
        } catch (Exception $e) {
            return false;
        }
        return false;
    }


     /**
     * Delete Single
     * @since 1.0.0
     * @return boolean
     */
    public function deleteSingle($key){
        $result = array();
        if (isset($key) && !empty($key)) {
            try {
                $object = $this->bucket->object($key);
                $object->delete();

                if (!$object->exists()) {
                    $result = array(
                        'success'   => true,
                        'code'      => 200,
                        'message'   => esc_html__('Deleted Successfully', 'media-cloud-sync'),
                    );
                } else {
                    $result = array(
                        'success'   => false,
                        'code'      => 200,
                        'message'   => esc_html__('File not deleted', 'media-cloud-sync'),
                    );
                }
            } catch (Exception $e) {
                $result = array(
                    'success'   => false,
                    'code'      => 200,
                    'message'   => $e->getMessage(),
                );
            }
        } else {
            $result = array(
                'success'   => false,
                'code'      => 200,
                'message'   => esc_html__('Insufficient Data. Please try again', 'media-cloud-sync'),
            );
        }
        return $result;
    }


    /**
     * get presigned URL
     * @since 1.0.0
     * @return boolean
     */
    public function get_presigned_url($key) {
        $result = array();
        if (isset($key) && !empty($key)) {
            try {
                $object = $this->bucket->object($key);

                $expires = isset($this->settings['presigned_expire']) ? $this->settings['presigned_expire'] : 20;

                $presignedUrl =  $object->signedUrl(new \DateTime(sprintf('+%s  minutes', $expires)));

                if ($presignedUrl) {
                    $result = array(
                        'success'   => true,
                        'code'      => 200,
                        'file_url'  => $presignedUrl,
                        'message'   => esc_html__('Got Presigned URL Successfully', 'media-cloud-sync'),
                    );
                } else {
                    $result = array(
                        'success'   => false,
                        'code'      => 200,
                        'message'   => esc_html__('Error getting presigned URL', 'media-cloud-sync'),
                    );
                }
            } catch (Exception $e) {
                $result = array(
                    'success'   => false,
                    'code'      => 200,
                    'message'   => $e->getMessage(),
                );
            }
        } else {
            $result = array(
                'success'   => false,
                'code'      => 200,
                'message'   => esc_html__('Insufficient Data. Please try again', 'media-cloud-sync'),
            );
        }
        return $result;
    }


    /**
     * Generate file URL
     */
    private function generate_file_url($key){
        $domain = $this->get_domain();

        return apply_filters('wpmcs_generate_google_file_url',
            $domain . '/' . $this->bucket_name . '/' . $key,
            $domain, $key,
            $this->bucket_name
        );
    }


    /**
     * Get domain URL
     */
    public function get_domain() {
        $url_base = 'https://storage.googleapis.com';
        
        return $url_base;
    }
}
```
