Google Cloud in PHP

At this post I will give some examples of how to use Google APIs Client Library for PHP in order for interact with Google Cloud.

Google BigQuery API client library for PHP

First you need to download Google BigQuery API client library for PHP (download Google BigQuery API client library here).
Open it and use only the Google directory.
Before coding, please validate that you have a Google Cloud account and that you have the credentials. In the following examples you need to supply:

      PROJECT_ID
      CLIENT_ID
      SERVICE_ACCOUNT_NAME

PHP class to interact with Google Cloud API client library

ini_set('display_errors', 1);
set_time_limit(0);
error_reporting(E_ALL);
 
require_once 'Google/Client.php';
require_once 'Google/Auth/AssertionCredentials.php';
require_once 'Google/Service/Storage.php';
 
class UploadFilesToGoogleCloud{
    private $client = null;
    private $service_token;
    private $storageService;
    const KEY_FILE = 'privatekey.p12';
    const PROJECT_ID = "723909334651";
    const CLIENT_ID = "723909334651-trdcn1mjaeoqi3gmahvesdr6tgthqovv.apps.googleusercontent.com";
    const SERVICE_ACCOUNT_NAME = "723909334651-trdcn1mjaeoqi3gmahvesdr6tgthqovv@developer.gserviceaccount.com";
    const SCOPES_STR = 'https://www.googleapis.com/auth/devstorage.full_control';
 
    function __construct() {
        //TODO: initialize log file or getting properties instead of using Consts 
    }
 
    /**
    * Initialize the Class and authenticate to the GC API
     * @param $appName:string Application Name
     **/
    function init($appName){
        $this->client = new Google_Client("Google_Config.ini");//"Google_Config.ini"
        $this->client->setApplicationName($appName);
        $this->client->setClientId(self::CLIENT_ID);
        $key = file_get_contents(self::KEY_FILE);
        $cred = new Google_Auth_AssertionCredentials(
            self::SERVICE_ACCOUNT_NAME,
            array(self::SCOPES_STR),
            $key);
        $this->client->setAssertionCredentials($cred);
 
        $this->client->setClassConfig('Google_IO_Abstract',
                array (
                    'request_timeout_seconds' => 0,
                    CURLOPT_CONNECTTIMEOUT => 0,
                    CURLOPT_TIMEOUT => 0,
                    CURLOPT_TIMEOUT_MS => 0
                ),
                array('options' => array(
                    CURLOPT_CONNECTTIMEOUT => 0,
                    CURLOPT_TIMEOUT => 0
                    )
                )
            );
 
        $this->client->setClassConfig('Google_IO_Curl',
                'options',
                array(
                    CURLOPT_CONNECTTIMEOUT => 0,
                    CURLOPT_TIMEOUT => 0
                )
            );
 
        $this->writeToLog("CLASSES".var_dump($this->client-> getClassConfig('Google_IO_Abstract')));
 
        if ($this->client->getAuth()->isAccessTokenExpired()) {
            $this->client->getAuth()->refreshTokenWithAssertion($cred);
            $this->service_token = $this->client->getAccessToken();
            if(empty ($this->service_token)){
                $this->writeToLog("auth API TOKEN IS EMPTY error: \n");
            }
        }
 
        $this->storageService = new Google_Service_Storage($this->client);
    }
 
    /**
     * uploading the file to the google cloud.
     * @param $bucketName :string bucket (library) name in google cloud.
     * @param $fileName :string file name to create in the Google cloud include suffix.
     * @param $fileFullPath :string full path include file name of the local file to upload
     * */
    public function uploadFile($bucketName, $fileName, $fileFullPath){
        $objects = $this->storageService->objects;
        $postBody = array('data' => file_get_contents($fileFullPath), 'uploadType' => 'media');//media  -  resumable   ...  , 'contentType' => 'media'
        $gso = new Google_Service_Storage_StorageObject();
        $gso->setName($fileName);// the file name to create on GoogleCloud
        $resp = $objects->insert($bucketName, $gso ,$postBody);
        return $resp;
    }
 
    /**
    * Get File from the Google Cloud
    * @param $bucketName - string the Bucket Name
    * @param $fileName - string the File Name inside the Bucket
    * @return $responseHeaders - Google_Http_Request / NULL if not exist.
    **/
    public function getFile($bucketName, $fileName){
        try{
             // getting the file link
             $csvFile = $this->storageService->objects->get($bucketName, $fileName);
             $fileLink = $csvFile['mediaLink'];
             // getting and return the file (with All Meta Data)
 
             $request = new Google_Http_Request($fileLink, 'GET', null, null);
             return $this->storageService->getClient()->getAuth()->authenticatedRequest($request);
        } catch (Google_Service_Exception $gsex) {
             $this->writeToLog("Google_Service_Exception: ".$gsex->getMessage());
             return null;
        }
    }
 
    /**
    * Append Date to Google Cloud File
    * @param string $bucketName - the Bucket Name.
    * @param string $gcFileName - the File Name inside the Bucket.
    * @param string $data - the DATA (CSV FORMAT) for appending to the file.
    * @return $responseHeaders - Google_Http_Request.<<<<<<<<<<<<<<<<<<<<
    */
    public function appendDataToFile($bucketName, $gcFileName, $data){
 
        try{
            $tempCSVFileName = "Temp".date('Y_m_d_H_i_s').'.csv';
            $tempFileFullPath = "logs/".$tempCSVFileName;
            $csvTempFile = fopen($tempFileFullPath, "w");
 
            $GCFileResponseHeaders = $this->getFile($bucketName, $gcFileName);
            //$this->writeToLog("GCFileResponseHeaders : ".$GCFileResponseHeaders->getResponseBody());
            if (null == $GCFileResponseHeaders ){
                // create new file with the DATA
                $this->writeToLog("DATA : ".json_encode($data));
                fputcsv($csvTempFile, $data);
                //fwrite($csvTempFile, $data);
            }else{
                // append the DATA to the file and Upload it (OVERWIRTE)
                $GCFileContent = $GCFileResponseHeaders->getResponseBody();
                $this->writeToLog("Google Cloud File CONTENT : ".$GCFileContent);
                fwrite($csvTempFile, $GCFileContent);
                $this->writeToLog("Data To Append : ".json_encode($data));
                fputcsv($csvTempFile, $data);//
                //fwrite($csvTempFile, json_encode($data));
            }
            fclose($csvTempFile);
 
            $fullPath = $this->uploadFile($bucketName, $gcFileName, $tempFileFullPath);
 
            $this->writeToLog("FULL PATH : ".$fullPath['mediaLink']);
            if(null == $fullPath){
                throw new Exception("Error: could not Upload File To Google Cloud.");
            }
            return $fullPath['mediaLink'];
        } catch (Exception $ex) {
            $this->writeToLog("Failed to append data to GC file ".$ex->getMessage());
            return false;
        }
    }
 
    /**
    * Download a file's content.
    *
    * @param Google_Servie_Drive $service Drive API service instance.
    * @param Google_Servie_Drive_DriveFile $file Drive File instance.
    * @return String The file's content if successful, null otherwise.
    */
   function downloadFile($service, $file) {
      // $service = Google_Servie_Driv;
     $downloadUrl = $file->getDownloadUrl();
     if ($downloadUrl) {
                                        // $url,    $method = 'GET',$headers = array(),$postBody = null
       $request = new Google_Http_Request($downloadUrl, 'GET', null, null);
       $httpRequest = $service->getClient()->getAuth()->authenticatedRequest($request);
       if ($httpRequest->getResponseHttpCode() == 200) {
         return $httpRequest->getResponseBody();
       } else {
         // An error occurred.
         return null;
       }
     } else {
       // The file doesn't have any content stored on Drive.
       return null;
     }
   }
 
 
 
 
 
    public function testAppendFileToFile($bucketName, $fileName, $fileFullPath){
        $options = ['gs' => ['Content-Type' => 'text/plain']];
        $ctx = stream_context_create($options);
        file_put_contents('gs://'.$bucketName.'/'.$fileName, file_get_contents($fileFullPath), FILE_APPEND, $ctx);
    }
 
    public function testAppendDataToFile($bucketName, $fileName, $data){
        $this->uri_array = array(
            'gs://'.$bucketName.'/'.$fileName
        );
        $options = ['gs' => ['Content-Type' => 'text/plain']];
        $ctx = stream_context_create($options);
        file_put_contents("gs://.$bucketName./.$fileName", $data, FILE_APPEND, $ctx);//"gs://$bucketName/$fileName"
    }
 
    /**
     * get the file details from the google cloud.
     * @param $bucketName:string bucket (library) name in google cloud.
     * @param $fileName:string file name of file in the Google cloud include suffix.
     * @return Google_Service_Storage_StorageObject
     * */
    public function getFileDetails($bucketName, $fileName){
        $objects = $this->storageService->objects; // Google_Service_Storage_Objects_Resource
		try{
			$resp = $objects->get($bucketName, $fileName);
			return $resp;
		}catch(Google_Service_Exception $e){
			return FALSE;
		}
    }
 
 
    /**
     * get the bucket's objects list from the google cloud.
     * @param $bucketName:string bucket (library) name in google cloud.
     * @param $arr:dissociative array .
     * @return Google_Service_Storage_StorageObject
     * */
    public function getList($bucketName, $arr){
        $objects = $this->storageService->objects; // Google_Service_Storage_Objects_Resource
		try{
			$resp = $objects->listObjects($bucketName, $arr);
			return $resp;
		}catch(Google_Service_Exception $e){
			return FALSE;
		}
    }
 
 
    /**
     * get the file details from the google cloud.
     * @param $bucketName:string bucket (library) name in google cloud.
     * @param $fileName:string file name of file in the Google cloud include suffix.
     * @return Google_Service_Storage_StorageObject
     * */
    public function deleteFile($bucketName, $fileName){
        $objects = $this->storageService->objects; // Google_Service_Storage_Objects_Resource
        try{
            $resp = $objects->delete($bucketName, $fileName);
            return $resp;
        }catch(Google_Service_Exception $e){
            return FALSE;
        }
    }
 
    /**
     * Write message into log file.
     * @param $msg:string - message to write.
    **/
    public function writeToLog($msg) {
        echo "" . date('Y-m-d H:i:s') . " " . $msg . "\n";
    }
 
    /*
     *Service function for checking buckets
     * @param $bucketName:string - bucket Name
    */
    public function getBucket($bucketName){
        try{
            $bucket = $this->storageService->buckets->get($bucketName);
 
            return $bucket;
        }catch (Exception $ex){
            //insert to log: Auth error
            $this->writeToLog("getBucket API error: ".$ex->getMessage()."\n");
            echo "getBucket API error: ".$ex->getMessage()."\n";
            return false;
        }
    }
}

Example: uploading file to Google cloud

		$uploadFileService = new UploadFilesToGoogleCloud();
		$uploadFileService->init("dashboard");
		$uploadFileService->uploadFile($bucket, $cloud_csv_file_name, $local_csv_file_name);

Example: PHP class to handle flag on Google Cloud

 
require_once("UploadFilesToGoogleCloud.php");
 
// create for each report in specific directory a file that its name represent that latest date.
class GoogleCloudFlag {
 
    // archive_visionbi/LiveRail/[report]/flag/latest[Timestamp].txt
 
    private $FILE_PREFIX = "latest"; //self::CONSTANT
    private $FILE_SUFIX = ".txt"; //self::CONSTANT
    private $FLAG_DIRECTORY = "flag";
    private $bucket;
    private $report;
    private $folder;
 
    function __construct($bucket, $folder, $report) {
        $this->bucket = $bucket;
        $this->folder = $folder;
        $this->report = $report;
    }
 
    function getTimestamp() {
        $uploadFileService = new UploadFilesToGoogleCloud();
        $uploadFileService->init("dashboard");
        $arr = array('prefix' => "{$this->folder}/{$this->report}/{$this->FLAG_DIRECTORY}/{$this->FILE_PREFIX}");
        var_dump($arr);
        $files_details = $uploadFileService->getList($this->bucket, $arr);
        // case of more than one file is a bug. But need to take the one with the latest date
        if (!$files_details) {
            echo "Empty response\n";
            return null;
        }
        // TODO: deal with more than one result
        if (isset($files_details["items"]) && isset($files_details["items"][0]) && isset($files_details["items"][0]["name"])) {
            $name = $files_details["items"][0]["name"];
            var_dump($name);
            //'/(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})_(?<hour>\d{2})/'
            preg_match("/(?<date>\d{8}_\d{2})/", $name, $results);
            var_dump($results);
            return $results["date"];
        } else {
            return null;
        }
    }
 
    function setTimestamp($timestamp) {
        $this->clearAll();
        $file_name = "" . $this->FILE_PREFIX . $timestamp . $this->FILE_SUFIX;
        $file = fopen($file_name, "w");
        fclose($file);
        $cloud_file_name = "{$this->folder}/{$this->report}/{$this->FLAG_DIRECTORY}/{$file_name}";
        // upload the flag
        $uploadFileService = new UploadFilesToGoogleCloud();
        $uploadFileService->init("dashboard");
        $uploadFileService->uploadFile($this->bucket, $cloud_file_name, $file_name);
        unlink($file_name);
    }
 
    function clearAll() {
        $uploadFileService = new UploadFilesToGoogleCloud();
        $uploadFileService->init("dashboard");
        $arr = array('prefix' => "{$this->folder}/{$this->report}/{$this->FLAG_DIRECTORY}/{$this->FILE_PREFIX}");
        //var_dump($arr);
        $files_details = $uploadFileService->getList($this->bucket, $arr);
        // case of more than one file is a bug. But need to take the one with the latest date
        if (isset($files_details) && isset($files_details["items"])) {
            foreach ($files_details["items"] as $file_detail) {
                $uploadFileService->deleteFile($this->bucket, $file_detail["name"]);
            }
        }
    }
 
}
 
$googleCloudFlag = new GoogleCloudFlag($CLOUD_BUCKET, $CLOUD_DIR, $report_name);
$tmp = $googleCloudFlag->getTimestamp();
..
$googleCloudFlag->setTimestamp($date_on_file_name);
Leave a Reply

*