I am trying to download a google drive jpg using php to the server so that it is saved as a usuable jpg, such as when it is manually downloaded.
I can get the getWebContentLink from the filemeta and save 'a' file with extension .jpg:
$filemeta = $this->service->files->get($id,[
"fields"=>"*"
]);
$filename = public_path().'/test.jpg';
$url=$filemeta->getWebContentLink();
file_put_contents($filename, fopen($url, 'r'));
however this is not a true jpg and indeed cannot be displayed using an <img src="/test.jpg" />
element.
Setup:
public function __construct() {
$this->getClient();
$this->service= new Google_Service_Drive($this->client);
}
/**
* @return Google_Client
* @throws \Google_Exception
*/
protected function getClient() {
$client = new Google_Client();
$client->setApplicationName('Google Drive API PHP Quickstart');
//20200521$client->setScopes(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setScopes(Google_Service_Drive::DRIVE_READONLY);
// https://www.googleapis.com/auth/drive.readonly
$client->setAuthConfig(base_path().'/apicredentials/google/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 = base_path().'/apicredentials/google/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()));
}
$this->client=$client;
}
How about this answer?
In order to retrieve the file content with webContentLink
from outside, it is required to use the access token or the file is required to be shared publicly. So in your script, I think that the created file is the HTML data of the login page.
So how about the following workaround?
Download the file content with webContentLink
using the access token.
At first, share publicly the file on Google Drive. Then, download the file content using your current script.
Directly download the file content using Drive API. In this case, the modified script is as follows. And if you are using https://www.googleapis.com/auth/drive.metadata.readonly
as the scope, please modify to https://www.googleapis.com/auth/drive.readonly
.
$content = $this->service->files->get($id, array("alt" => "media"));
$filename = public_path().'/test.jpg';
file_put_contents($filename, $content->getBody());