1 year ago
#363126
Prashant
How to manage the verfication code automatically without user for google drive api
I am uploading files to google drive folder using php and Google Client API. I have created a new project in Google console. I have configured the oauth consent. Similarly I have obtained the credentials of client Id and Client Secret. I have created a component class to manage the API calls.
<?php
namespace app\components;
include __DIR__ . '/vendor/autoload.php';
use Yii;
use yii\base\Component;
use yii\base\InvalidConfigException;
use Google_Client;
use Google_Service_Drive;
class Upload extends Component
{
public function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Drive API PHP Quickstart');
$client->setRedirectUri('http://localhost/lwa/basic/web');
$client->setScopes(Google_Service_Drive::DRIVE);
$client->setAuthConfig("../credentials.json");
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// 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();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// 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;
}
}
Similarly I have a controller action which does the actual file uploading work in google drive folder.
public function actionCreate()
{
$model = new UploadExcel();
if ($model->load(Yii::$app->request->post())) {
$file_tmp = $_FILES["file"]["tmp_name"];
$model->filepath = UploadedFile::getInstance($model, 'filepath');
$file_name = basename($model->filepath);
$model->filepath->saveAs('uploads/'.$model->filepath);
$path = "uploads/".$file_name;
move_uploaded_file($file_tmp, $path);
function check_folder_exists( $folder_name ){
$client = \Yii::$app->upload->getClient();
$service = new Google_Service_Drive( $client );
$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;
}
function create_folder( $folder_name, $parent_folder_id=null ){
$folder_list = check_folder_exists( $folder_name );
// if folder does not exists
if( count( $folder_list ) == 0 ){
$client = \Yii::$app->upload->getClient();
$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'];
}
$folder_id = create_folder( "excel1" );
function insert_file_to_drive( $file_path, $file_name, $parent_file_id = null ){
$client = \Yii::$app->upload->getClient();
$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),
'mimeType' => 'application/octet-stream',
)
);
$is_success = false;
if( isset( $result['name'] ) && !empty( $result['name'] ) ){
$is_success = true;
}
return $is_success;
}
$success = insert_file_to_drive( $path , $file_name, $folder_id);
if( $success ){
ob_start();
echo "<script language='javascript'>";
echo "alert('File Uploaded successfully')";
echo "</script>";
} else {
ob_start();
echo "<script language='javascript'>";
echo "alert('Error has occured')";
echo "</script>";
}
function dd( ...$d ){
echo "<pre style='background-color:#000;color:#fff;' >";
print_r($d);
exit;
}
}
else{
return $this->render('create', [
'model' => $model,
]);
}
}
Files are getting uploaded to drive folder for some time. Each time the token gets expired, I need to go to command prompt and enter the verification code. The code I need to grab from the URL and then paste in the command prompt to generate a new token.json file. So it is becoming a complex job. All the time users will not be able to copy the code from the url and then paste it in command propmt to generate the new token. So how to automatically referesh the token or save the token in the session so that users are not invloved in entring the verification code. This should be handled automatically through code.
php
google-api
yii2
google-drive-api
google-api-php-client
0 Answers
Your Answer