I am trying to upload files to google drive using PHP code. I can't get API response whatever it is. Incase of successful upload response should be 200 and different error codes. I just want to get receive error codes. Can anyone help me with it. Bellow I have pasted my complete code. I am using function like check if folder already exists and if it does place file in it otherwise just create new folder and place file in it. I am trying to make my code fail safe, if an error is encountered it saves the particular file and error code. right now it is just returning critical error and breaks AJAX.
function getClient(){
$authdata = array (
'web' =>
array (
'client_id' => get_option("csc_gdrive_clientid"),
'project_id' => get_option("csc_gdrive_projectid"),
'auth_uri' => "https://accounts.google.com/o/oauth2/auth",
'token_uri' => "https://oauth2.googleapis.com/token",
'auth_provider_x509_cert_url' => "https://www.googleapis.com/oauth2/v1/certs",
'client_secret' => get_option("csc_gdrive_clientsecret"),
),
);
include( plugin_dir_path( __FILE__ ) . '../vendor/autoload.php');
$client = new Google_Client();
$client->setApplicationName('Google Drive API PHP Quickstart');
$client->setScopes(Google_Service_Drive::DRIVE);
$client->setAuthConfig($authdata);
$client->setAccessType('offline');
// $client->setPrompt('select_account consent');
$client->setRedirectUri(get_option("csc_gdrive_redirecturi"));
// Load previously authorized token from a file, if it exists.
// The file key_config.txt stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = plugin_dir_path( __FILE__ ) .'111key_config.txt';
if (!file_exists($tokenPath)) {
return;
} else{
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
if (file_exists($tokenPath)){
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
$authCode = get_option('csc_gdrive_token');
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
}
}
return $client;
}enter code here
function create_folder( $folder_name, $parent_folder_id=null ){
//$folder_list = $this->check_folder_exists( $folder_name );
// if folder does not exists
//if( count( $folder_list ) == 0 ){
$client = $this->getClient();
if($client){
$service = new Google_Service_Drive( $client );
$folder = new Google_Service_Drive_DriveFile();
$folder->setName( $folder_name );
$folder->setMimeType('application/vnd.google-apps.folder');
if( !empty( $parent_folder_id ) ){
$folder->setParents( [ $parent_folder_id ] );
}
$result = $service->files->create( $folder );
$folder_id = null;
if( isset( $result['id'] ) && !empty( $result['id'] ) ){
$folder_id = $result['id'];
}
return $folder_id;
}
//}
//return $folder_list[0]['id'];
}
// This will check folders and sub folders by name
function check_folder_exists( $folder_name, $parent_folder_id=null){
$client = $this->getClient();
if($client){
$service = new Google_Service_Drive( $client );
if ($parent_folder_id){
$parameters['q'] = "mimeType='application/vnd.google-apps.folder' and name='$folder_name' and trashed=false and '$parent_folder_id' in parents";
} else {
$parameters['q'] = "mimeType='application/vnd.google-apps.folder' and name='$folder_name' and trashed=false";
}
$files = $service->files->listFiles($parameters);
$op = [];
foreach( $files as $k => $file ){
$op[] = $file;
}
return $op;
}
}
// This will insert file into drive and returns boolean values.
function insert_file_to_drive( $file_path, $file_name, $parent_file_id = null ){
$client = $this->getClient();
if($client){
$service = new Google_Service_Drive( $client );
$file = new Google_Service_Drive_DriveFile();
$file->setName( $file_name );
if( !empty( $parent_file_id ) ){
$file->setParents( [ $parent_file_id ] );
}
$result = $service->files->create(
$file,
array(
'data' => file_get_contents($file_path.'/'.$file_name),
'mimeType' => 'application/octet-stream',
)
);
$is_success = false;
if( isset( $result['name'] ) && !empty( $result['name'] ) ){
$is_success = true;
}
return $is_success;
}
}
Related
I have tried uploading a video to YouTube channels using by the YouTube Data API, by composer:
"require": {
"google/apiclient": "^2.7",
"hybridauth/hybridauth": "~3.4.0",
"guzzlehttp/guzzle": "^7.0"
}
The video is uploaded successfully, but YouTube marks every video uploaded into it as private. Does anybody know how to fix this scenario?
public function upload_video_on_youtube($id, $arr_data)
{
$result_data = array();
$channel_id = $id;
$uploaded = false;
$stopper = 0;
while ($uploaded == false && $stopper == 0) {
$arr_data['summary'] = $this->getrandomstring(10);
$arr_data['title'] = $this->getrandomstring(10);
$client = new Google_Client();
$arr_token = $this->getAccessToken($channel_id);
if ($arr_token['error'] == false) {
$res = array();
$accessToken = array(
'access_token' => $arr_token['access_token']
);
$client->setAccessToken($accessToken);
$service = new Google_Service_YouTube($client);
$video = new Google_Service_YouTube_Video();
$videoSnippet = new Google_Service_YouTube_VideoSnippet();
$videoSnippet->setDescription($arr_data['summary']);
$videoSnippet->setTitle($arr_data['title']);
$video->setSnippet($videoSnippet);
$videoStatus = new Google_Service_YouTube_VideoStatus();
$videoStatus->setPrivacyStatus('unlisted');
$video->setStatus($videoStatus);
try {
$response = $service->videos->insert(
'snippet,status',
$video,
array(
'data' => file_get_contents($arr_data['video_path']),
'mimeType' => 'video/*',
'uploadType' => 'multipart'
)
);
if (isset($response->id)) {
$video_id = $response->id;
$res['error'] = false;
$res['response'] = $video_id;
array_push($result_data, $res);
$uploaded = true;
return $result_data;
}
} catch (Exception $e) {
if (401 == $e->getCode()) {
// echo ($arr_token['email'] . " Youtube Access token expired");
$refresh_token = $this->get_refersh_token($channel_id);
$client = new GuzzleHttp\Client(['base_uri' => 'https://accounts.google.com']);
$response = $client->request('POST', '/o/oauth2/token', [
'form_params' => [
"grant_type" => "refresh_token",
"refresh_token" => $refresh_token,
"client_id" => $arr_token['client_id'],
"client_secret" => $arr_token['client_secret'],
],
]);
$data = json_decode($response->getBody());
$data->refresh_token = $refresh_token;
$this->update_access_token($channel_id, json_encode($data));
$uploaded = false;
} elseif (403 == $e->getCode()) {
// echo ($arr_token['email'] . ' Youtube channel quota exceeded');
$channel_id = $channel_id + 1;
$uploaded = false;
}
}
} else if ($arr_token['error'] == true) {
$res['error'] = true;
$res['response'] = "Your Daily Upload Quota is Exceeded";
array_push($result_data, $res);
$stopper = 1;
return $result_data;
}
}
}
If you check the documentation for videos.insert you will see that all videos that are uploaded by apps that have not gone through the verification process will be set to private.
Once you go through the verification process you will be able to set your videos to public
This is an update after some clarity from Google.
At the top of the Video.insert page you will see it states.
Apps that dont need to be verified can just go though an audit is not verification, these are two different things. You need to apply for an audit. YouTube API Services - Audit and Quota Extension Form
I'm trying to create a copy of a document using the Google Docs Api, and then edit it that copy by inserting text into it. So, I've looked at the documentation and seemingly implemented it exactly the way it says.
<?php
//That is, if this is just a regular login
//Personal Files
require("loginManager.php");
require("globals.php");
require("googleDrive.php");
//Moodle files
require("../config.php");
require("../my/lib.php");
require("../files/renderer.php");
require("../course/lib.php");
//Google Docs
$CREDENTIALS_PATH = "../../" . "vendor/autoload.php";
require ($CREDENTIALS_PATH);
//Example code
$copyTitle = 'Copy Title';
$documentId = "1vYyeGLbadFi0sl9g2LEJSZCB4YiGOpCb";
$copy = new Google_Service_Drive_DriveFile(array(
'name' => $copyTitle
));
//Initialize necessary client variables
$desiredPath = "../../credentials.json";
$authCode = (isset($_GET["code"]) ? $_GET["code"]:"");
GoogleDrive::setAuthCode($authCode);
$client = GoogleDrive::getClient($desiredPath, $FULLSCRIPT);
$docServices = new Google_Service_Docs($client);
$driveServices = new Google_Service_Drive($client);
$files = $driveServices->files;
$documents = $docServices->documents;
$driveResponse = $files->copy($documentId, $copy);
$documentCopyId = $driveResponse->id;
//Create desiredRequests
$desiredRequests = array(new Google_Service_Docs_Request(array(
'insertText' => array(
'text' => 'Hello world!',
'location' => array(
'index' => 25)))));
$batchUpdateRequests = new Google_Service_Docs_BatchUpdateDocumentRequest(array(
'requests' => $desiredRequests));
$docChangeResponse = $documents->batchUpdate($documentCopyId, $batchUpdateRequests);
echo $OUTPUT->header();
echo $OUTPUT->custom_block_region('content');
echo $OUTPUT->footer();
//Check if there's any get actions that need to be serviced
$getVariable = filter_input(INPUT_GET, "action");
if($getVariable == "openFileManager") {core_files_renderer::render_form_filemanager();}
else if($getVariable == "createCourse")
{
/*Important note: there are two types of ids when it comes to courses
*
* Programmer's Notes:
*
* -$instance is the instance of a record of from the enrol table
* -the enrol table stores instances of courses...so does mdl_course
* -idnumber and id, the latter is the actual primary key, the other is
* I guess is for school admins or course creators to be able to number
* the courses according to their own system. idnumber can be null.
*
*/
$enrollmentPlugin = enrol_get_plugin("manual");
if($enrollmentPlugin)
{
//Create data for course_request
$data = new stdClass();
$data->requester = $USER->id;
$data->id = 1;
$course_request_object = new course_request($data);
unset($data);
//create data for new course
$data = new stdClass();
$data->fullname = 'Math';
$data->shortname = 'Math 7';
$data->summary = 'Awesome!';
$data->summaryformat = FORMAT_PLAIN;
$data->format = 'topics';
$data->newsitems = 0;
$data->numsections = 5;
//$data->category = $course_request_object->get_category();
$data->category = 1;
$course = create_course($data);
//Instance is the record from the enrol table
$instanceid = $enrollmentPlugin->add_instance($course);
$instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'manual'), '*', MUST_EXIST);
$enrollmentPlugin->enrol_user($instance, $USER->id);
}
}
else if($getVariable == "appendDocument")
{
$courseID = filter_input(INPUT_GET, "courseID");
$fs = get_file_storage();
$data = array(
'contextid' => $courseID, // ID of context
'component' => 'course_myarea', // usually = table name
'filearea' => 'myarea', // usually = table name
'itemid' => 0, // usually = ID of row in table
'filepath' => '/', // any path beginning and ending in /
'filename' => 'myfile.txt'
);
$content = "hellp worldl";
$fs->create_file_from_string($data, $content);
}
else if($getvariable == null)
{
//if there are no get paramaters then it's a first time entry
//get all of user's courses, files, etc
$courses = enrol_get_all_users_courses($USER->id);
global $DB;
foreach($courses as $currentCourse)
{
$desiredID = $currentCourse->id;
$desiredFiles = $DB->get_record('files', array('contextid'=> $desiredID));
$contentHash = $desiredFiles->contenthash;
$dir1 = substr($contentHash, 0, 2); $dir2 = substr($contentHash, 2, 2);
$desiredPath = $CFG->dirrot."../../../../moodledata/filedir/"
.$dir1."/".$dir2."/".$contentHash;
$myFile = file_get_contents($desiredPath);
$type = mime_content_type($desiredPath);
$contentTypes = array("pdf" => "application/pdf",
"txt" => "text/plain");
//header("Content-Type: application/pdf");
//readfile($desiredPath, false, $foo);
$myFile = file_get_contents("goedel.pdf");
$foo = 3;
}
}
?>
Here's where GoogleDrive::getClient is defined in case it helps
class GoogleDrive
{
private static $AUTH_CODE;
public static function setAuthCode($desiredCode)
{
self::$AUTH_CODE = $desiredCode;
}
public static function getClient($credentialsPath, $callbackScript)
{
$client = new Google_Client();
$client->setApplicationName('MyApp');
$client->setScopes(Google_Service_Drive::DRIVE);
$client->setAuthConfig($credentialsPath);
$client->setAccessType('online');
$client->setPrompt('select_account consent');
$desiredVariable = self::$AUTH_CODE;
if($desiredVariable != null)
{
$accessToken = $client->fetchAccessTokenWithAuthCode($desiredVariable);
$client->setAccessToken($accessToken);
return $client;
}
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
$client->setRedirectUri($callbackScript);
redirect($authUrl);
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
}
However, when I run the previous code I get this error.
"{
"error": {
"code": 400,
"message": "This operation is not supported for this document",
"errors": [
{
"message": "This operation is not supported for this document",
"domain": "global",
"reason": "failedPrecondition"
}
],
"status": "FAILED_PRECONDITION"
}
}
"
Any help or direction will be greatly appreciated.
Edit 1: I've changed the script to reflect Tanaike's solution
I believe your situation and goal as follows.
You have already been able to use Google Docs API.
The script of a copy of a document worked.
You want to remove the error in your question.
For this, how about this modification?
From:
$desiredRequests = new Google_Service_Docs_Request(array(
'insertText' => array(
'text' => 'Hello world!',
'location' => array(
'index' => 25))));
In your script, when $batchUpdateRequests is retrieved, it becomes as follows.
{"requests":{"createNamedRangeType":{},"createNamedRangeDataType":{},"createParagraphBulletsType":{},"createParagraphBulletsDataType":{},"deleteContentRangeType":{},"deleteContentRangeDataType":{},"deleteNamedRangeType":{},"deleteNamedRangeDataType":{},"deleteParagraphBulletsType":{},"deleteParagraphBulletsDataType":{},"deletePositionedObjectType":{},"deletePositionedObjectDataType":{},"deleteTableColumnType":{},"deleteTableColumnDataType":{},"deleteTableRowType":{},"deleteTableRowDataType":{},"insertInlineImageType":{},"insertInlineImageDataType":{},"insertTableRowType":{},"insertTableRowDataType":{},"insertTextType":{},"insertTextDataType":{},"replaceAllTextType":{},"replaceAllTextDataType":{},"updateParagraphStyleType":{},"updateParagraphStyleDataType":{},"updateTextStyleType":{},"updateTextStyleDataType":{},"internal_gapi_mappings":{},"modelData":{},"processed":{},"insertText":{}}}
I think that this is the reason of your issue.
To:
$desiredRequests = array(new Google_Service_Docs_Request(array(
'insertText' => array(
'text' => 'Hello world!',
'location' => array(
'index' => 25)))));
In this modified script, when $batchUpdateRequests is retrieved, it becomes as follows.
{"requests":[{"insertText":{"text":"Hello world!","location":{"index":25,"segmentId":null}}}]}
In this request body, I could confirm that it worked.
Note:
If an error like Invalid requests[0].insertText: Index 25 must be less than the end index of the referenced segment occurs, please modify 'index' => 25 to 'index' => 1.
Reference:
Method: documents.batchUpdate
I have the error saying that permission denied. I already tried this (giving view access to the google credential), and this. And everything doesnt work. I already enable the API for the google drive and also did this :
gcloud components update
gcloud auth login --enable-gdrive-access
I'm using PHP.
Here's the Code
<?php
ini_set("memory_limit", "2048M");
ini_set('max_execution_time', 7200); //3600 seconds = 60 minutes
if (!defined('BASEPATH'))
exit('No direct script access allowed');
use Google\Cloud\BigQuery\BigQueryClient;
use Google\Cloud\ServiceBuilder;
use Google\Cloud\ExponentialBackoff;
require 'assets/SDK/vendor/autoload.php';
//require 'assets/library/vendor/autoload.php';
require_once 'assets/library/google-api-php-client/vendor/autoload.php';
define('APPLICATION_NAME', 'asd');
define('CLIENT_SECRET_PATH', 'assets/library/auth/asd.json');
define('PROJECT_ID','qwe');
define('SCOPES', implode(' ', array(
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive.metadata',
'https://www.googleapis.com/auth/drive.readonly')
));
public function index(){
$myFile = "assets/library/auth/session_bq2.txt";
if(file_exists($myFile)){
#$fh = fopen($myFile, 'r');
// echo 'filesize '.filesize($myFile);
$session = fread($fh, filesize($myFile));
fclose($fh);
//echo '--refreshToken index '.$session;
}
$client = new Google_Client();
$client->setAccessType('offline');
$client->setClientId('asd.apps.googleusercontent.com');
$client->setClientSecret('asds');
$client->setState('asd');
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
if (isset($session) && $session) {
//Set the new access token after authentication
$client->setAccessToken($session);
//json decode the session token and save it in a variable as object
$sessionToken = json_decode($session);
//Save the refresh token (object->refresh_token) into a cookie called 'token' and make last for 1 month
setcookie('access_token', $sessionToken->refresh_token , time()+2678400);
$cookie = isset($_COOKIE['access_token']) ? $_COOKIE['access_token'] : "";
if(!empty($cookie)){
$client->refreshToken($cookie);
}
$client->setAccessToken($session);
}
else{
$tes = $client->getRefreshToken();
$client = new Google_Client();
$client->setAccessType('offline');
$client->setClientId('asd.apps.googleusercontent.com');
$client->setRedirectUri('qwe');
$client->setClientSecret('asd');
$client->setState('asd');
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$myfile = fopen("assets/library/auth/session_bq2.txt", "w") or die("Unable to open file!");
$txt = json_encode($client->getAccessToken());
fwrite($myfile, $txt);
fclose($myfile);
header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);
}
else{
$oauth2_client_id = 'asd.apps.googleusercontent.com';
// $oauth2_redirect = 'asd';
$oauth2_redirect = 'http://' . $_SERVER['HTTP_HOST'] . 'asd';
$oauth2_server_url = 'https://accounts.google.com/o/oauth2/auth';
$query_params = array(
'response_type' => 'code',
'access_type' => 'offline',
'client_id' => $oauth2_client_id,
'scope' => SCOPES,
'redirect_uri' => $oauth2_redirect,
'state' => 'asd',
'approval_prompt' => 'force'
);
$forward_url = $oauth2_server_url . '?' . http_build_query($query_params);
header('Location: ' . $forward_url);
}
}
$service = new Google_Service_Bigquery($client);
$query="SELECT * FROM [queryspreadsheet] LIMIT 10";
putenv('GOOGLE_APPLICATION_CREDENTIALS='.dirname(__FILE__) . '/assets/library/auth/MyProject-f0b4007b2f57.json');//this can be created with other ENV mode server side
$client->useApplicationDefaultCredentials();
$builder = new ServiceBuilder([
'projectId' => 'asd',
]);
$bigQuery = $builder->bigQuery();
$job = $bigQuery->runQueryAsJob($query);
$info=$job->info();
$queryResults = $job->queryResults();
/*$queryResults = $bigQuery->runQuery(
$query,
['useLegacySql' => true]);*/
// var_dump($queryResults);die;
if ($queryResults->isComplete())
{
$i = 0;
$rows = $queryResults->rows();
foreach ($rows as $row)
{
$i++;
$result[$i] = $row;
}
}
else
{
throw new Exception('The query failed to complete');
}
$i = 0;
$i++;
var_dump($result);die;
return $result;
}
Does anyone have any idea what did I miss? Thanks.
Working on a WP plugin. It's end purpose is to serve as an inspection calendar for home inspectors. We're working with a Google Calendar that is already loaded full of events.
I am authenticating via Oauth2 & a Service account. The plugin needs only to access the inspection company's data, no other private user data.
Here's the code:
// Set up identity ------------------------------------.
$client_email = "XXXXXX#XXXXXXXXXX.iam.gserviceaccount.com";
$private_key = file_get_contents( EC_INSPECT_CAL_INC . "/HE_Web_1.p12" );
$scope = [ "https://www.googleapis.com/auth/calendar","https://www.googleapis.com/auth/calendar.readonly","https://www.google.com/calendar/feeds" ];
$credentials = new \Google_Auth_AssertionCredentials(
$client_email,
$scope,
$private_key
);
// Build Config Obj ------------------------------------.
$config = new \Google_Config();
$config->setClassConfig('Google_Cache_File', array('directory' => EC_INSPECT_CAL_INC . '/tmp/cache'));
// Instantiate Client Connection ------------------------.
$client = new \Google_Client( $config );
$client->setAssertionCredentials( $credentials );
if( $client->getAuth()->isAccessTokenExpired() )
$client->getAuth()->refreshTokenWithAssertion();
$service = new \Google_Service_Calendar( $client );
$calendarList = $service->calendarList->listCalendarList();
while( true )
{
foreach( $calendarList->getItems() as $calendarListEntry )
{
// get events
$events = $service->events->listEvents( $calendarListEntry->id );
foreach( $events->getItems() as $event )
echo "-----".$event->getSummary() . "<br>";
}
$pageToken = $calendarList->getNextPageToken();
if( !$pageToken ) break;
$optParams = array('pageToken' => $pageToken);
$calendarList = $service->calendarList->listCalendarList($optParams);
}
}
If I var_dump the following:
var_dump( $service->calendarList->listCalendarList() );
It results in:
array(0) { }
My wife would like me to stop cursing in front of the dogs, but I can't seem to figure out what I'm overlooking. The calendar is loaded with content, and I (AFAIK) am authenticating ... So where's the goods??
I am trying to get accessToken using refreshToken, below I have posted my code please someone guide me.
It is from a wordpress plugin I am developing, I only need to retrieve pageViews
and pagePath so not preferring using a available plugin.
Taken reference from Use OAuth Refresh Token to Obtain New Access Token - Google API
if( isset( $this->options['authenication_code'] ) ){ //plugin setting page settings
global $wpdb;
$resultset = $wpdb->get_row( 'SELECT `refreshToken` FROM ' . $wpdb->prefix . 'analyticaAnalytics WHERE authenication_code ="' . $this->options["authenication_code"] . '"', ARRAY_A );
var_dump( $resultset['refreshToken'] ); //retrieved refreshToken from database
if ($client->isAccessTokenExpired()) { //boolean true
$client->refreshToken( $resultset['refreshToken'] );
var_dump( $client );//getting blank
}
}
../google-api-php-client/src/Google/Auth/oauth2.php
private function refreshTokenRequest($params)
{
if (isset($params['assertion'])) {
$this->client->getLogger()->info(
'OAuth2 access token refresh with Signed JWT assertion grants.'
);
} else {
$this->client->getLogger()->info('OAuth2 access token refresh');
}
$http = new Google_Http_Request(
self::OAUTH2_TOKEN_URI,
'POST',
array(),
$params
);
$http->disableGzip();
$request = $this->client->getIo()->makeRequest($http);
//var_dump( $request );exit;//response 400, invalid grant
$code = $request->getResponseHttpCode();
$body = $request->getResponseBody();
if (200 == $code) {
$token = json_decode($body, true);
if ($token == null) {
throw new Google_Auth_Exception("Could not json decode the access token");
}
if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
throw new Google_Auth_Exception("Invalid token format");
}
if (isset($token['id_token'])) {
$this->token['id_token'] = $token['id_token'];
}
$this->token['access_token'] = $token['access_token'];
$this->token['expires_in'] = $token['expires_in'];
$this->token['created'] = time();
} else {
throw new Google_Auth_Exception("Error refreshing the OAuth2 token, message: '$body'", $code);
}
}
After spending a lot of time I got the error is responsecode 400 for $request = $this->client->getIo()->makeRequest($http); and that is invalid grant.
full code
This is how , I solved the problem, We need to store the refreshToken in our database and using that refreshToken, We can get another accessToken .which can be used to get the result and it does not need another authentication .
<?php
$client = new Google_Client();
$client->setAuthConfigFile(plugin_dir_url( __FILE__ ) . '/client_secrets.json');
$client->setRedirectUri( site_url() . '/wp-admin/admin.php?page=analytica-admin-settings');
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);
$client->setIncludeGrantedScopes(true);
$client->setAccessType('offline');
if ( isset( $_GET['code'] )) {
if($client->isAccessTokenExpired()){
$client->authenticate($_GET['code']);
$accessToken = $client->getAccessToken();
$refreshToken = $client->getRefreshToken();
$analytica_tokens = json_encode( array( 'time' => current_time( 'mysql' ),'accessToken' => $accessToken, 'refreshToken' => $refreshToken ) );
update_option( 'analytica_tokens', $analytica_tokens );
}
} else {
$resultset = json_decode(get_option('analytica_tokens'));
if ($client->isAccessTokenExpired()) {
if( isset( $resultset ) ){
$refreshToken = $resultset->refreshToken;
$client->refreshToken( $refreshToken );
$accessToken = $client->getAccessToken();
$analytica_tokens = json_encode( array( 'time' => current_time( 'mysql' ), 'accessToken' => $accessToken, 'refreshToken' => $refreshToken ) );
update_option( 'analytica_tokens', $analytica_tokens );
} else {
echo 'You need to reauthorize the application to get the analytics report.';
}
}
}
$auth_url = $client->createAuthUrl();
?>
<a class="connect-to-google-analytics" href='<?php echo $auth_url; ?>' id="loginText">Connect To Your Google Analytics Account </a>
<?php
if( isset($accessToken) ){
$_SESSION['access_token'] = $accessToken ? $accessToken : $refreshToken;
$client->setAccessToken($_SESSION['access_token']);
// Create an authorized analytics service object.
$analytics = new Google_Service_Analytics($client);
// Get the first view (profile) id for the authorized user.
$profile = $this->getFirstProfileId($analytics);
// Get the results from the Core Reporting API and print the results.
$this->results = $this->getResults($analytics, $profile);
}
?>